From c0bce256e108f7e50e8c7882c243469c1b4c5f49 Mon Sep 17 00:00:00 2001 From: benthetechguy Date: Tue, 31 May 2022 21:15:37 -0400 Subject: [PATCH 01/87] Add x86 to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d85df102..6e080045 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight, AstroBWT and [GhostRider](https://github.com/xmrig/xmrig/tree/master/src/crypto/ghostrider#readme) unified CPU/GPU miner and [RandomX benchmark](https://xmrig.com/benchmark). Official binaries are available for Windows, Linux, macOS and FreeBSD. ## Mining backends -- **CPU** (x64/ARMv7/ARMv8) +- **CPU** (x86/x64/ARMv7/ARMv8) - **OpenCL** for AMD GPUs. - **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/xmrig/xmrig-cuda). From 223add4e22881aff21f2b253ea1614fae67a0ae2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 2 Feb 2023 12:27:33 +0700 Subject: [PATCH 02/87] v6.19.1-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 67437bcb..0e4bbb02 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.0" +#define APP_VERSION "6.19.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 19 -#define APP_VER_PATCH 0 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 49f34e59a6fccaf3efc3b088be3f1966d5cf8d2d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 3 Feb 2023 23:08:54 +0700 Subject: [PATCH 03/87] Partially resolved deprecated methods warnings in OpenSSL 3.0. --- src/base/kernel/Platform.cpp | 10 ++++++---- src/base/net/tls/TlsGen.cpp | 8 ++++++-- src/base/net/tls/TlsGen.h | 8 ++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/base/kernel/Platform.cpp b/src/base/kernel/Platform.cpp index ef2b67eb..9baf77c2 100644 --- a/src/base/kernel/Platform.cpp +++ b/src/base/kernel/Platform.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #include "base/kernel/Platform.h" @@ -42,9 +41,12 @@ void xmrig::Platform::init(const char *userAgent) # ifdef XMRIG_FEATURE_TLS SSL_library_init(); SSL_load_error_strings(); + +# if OPENSSL_VERSION_NUMBER < 0x30000000L || defined(LIBRESSL_VERSION_NUMBER) ERR_load_BIO_strings(); ERR_load_crypto_strings(); - SSL_load_error_strings(); +# endif + OpenSSL_add_all_digests(); # endif diff --git a/src/base/net/tls/TlsGen.cpp b/src/base/net/tls/TlsGen.cpp index 42892053..ad2e648b 100644 --- a/src/base/net/tls/TlsGen.cpp +++ b/src/base/net/tls/TlsGen.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ static const char *kLocalhost = "localhost"; static EVP_PKEY *generate_pkey() { +# if OPENSSL_VERSION_NUMBER < 0x30000000L || defined(LIBRESSL_VERSION_NUMBER) auto pkey = EVP_PKEY_new(); if (!pkey) { return nullptr; @@ -53,6 +54,9 @@ static EVP_PKEY *generate_pkey() BN_free(exponent); return pkey; +# else + return EVP_RSA_gen(2048); +# endif } diff --git a/src/base/net/tls/TlsGen.h b/src/base/net/tls/TlsGen.h index c471c8ca..193dd2d5 100644 --- a/src/base/net/tls/TlsGen.h +++ b/src/base/net/tls/TlsGen.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,7 +55,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_TLSGEN_H */ +#endif // XMRIG_TLSGEN_H From 75474be060ac73b59ff29f41f3345070cca72874 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 3 Feb 2023 23:46:58 +0700 Subject: [PATCH 04/87] Fix warning. --- src/crypto/ghostrider/ghostrider.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index 0ce0976e..c0fddeac 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright 2018-2021 SChernykh - * Copyright 2016-2021 XMRig , + * Copyright 2018-2023 SChernykh + * Copyright 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #include "ghostrider.h" #include "sph_blake.h" #include "sph_bmw.h" @@ -574,7 +573,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct if (helper && (tune[cn_indices[0]].threads == 2) && (tune[cn_indices[1]].threads == 2) && (tune[cn_indices[2]].threads == 2)) { const size_t n = N / 2; - helper->launch_task([n, av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { + helper->launch_task([av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { const uint8_t* input = data; size_t input_size = size; From 540b223eabdb2d869073e5ef95ca17dc1ccdee3d Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 9 Feb 2023 13:55:11 +0700 Subject: [PATCH 05/87] Cleanup. --- cmake/flags.cmake | 24 ++++++------------------ src/base/net/dns/DnsRecord.cpp | 8 ++++---- src/base/net/tls/TlsContext.h | 12 +++++------- src/base/tools/Object.h | 13 ++++++++----- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 10386b17..f55ddcdc 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -10,7 +10,7 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") endif() if (CMAKE_BUILD_TYPE STREQUAL "Release") - add_definitions(/DNDEBUG) + add_definitions(-DNDEBUG) endif() include(CheckSymbolExists) @@ -32,7 +32,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") - add_definitions(/DHAVE_ROTR) + add_definitions(-DHAVE_ROTR) endif() if (WIN32) @@ -49,16 +49,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() - add_definitions(/D_GNU_SOURCE) - - if (${CMAKE_VERSION} VERSION_LESS "3.1.0") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() - - #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") - - add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE) + add_definitions(-D_GNU_SOURCE -DHAVE_BUILTIN_CLEAR_CACHE) elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) set(CMAKE_C_FLAGS_RELEASE "/MP /MT /O2 /Oi /DNDEBUG /GL") @@ -67,10 +58,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MP /Ob1 /Zi /DRELWITHDEBINFO") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MP /Ob1 /Zi /DRELWITHDEBINFO") - add_definitions(/D_CRT_SECURE_NO_WARNINGS) - add_definitions(/D_CRT_NONSTDC_NO_WARNINGS) - add_definitions(/DNOMINMAX) - add_definitions(/DHAVE_ROTR) + add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -DNOMINMAX -DHAVE_ROTR) elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) @@ -92,7 +80,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR) if (HAVE_ROTR) - add_definitions(/DHAVE_ROTR) + add_definitions(-DHAVE_ROTR) endif() endif() @@ -105,6 +93,6 @@ endif() if (NOT WIN32) check_symbol_exists("__builtin___clear_cache" "stdlib.h" HAVE_BUILTIN_CLEAR_CACHE) if (HAVE_BUILTIN_CLEAR_CACHE) - add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE) + add_definitions(-DHAVE_BUILTIN_CLEAR_CACHE) endif() endif() diff --git a/src/base/net/dns/DnsRecord.cpp b/src/base/net/dns/DnsRecord.cpp index bfa84613..3bf8f097 100644 --- a/src/base/net/dns/DnsRecord.cpp +++ b/src/base/net/dns/DnsRecord.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,11 +46,11 @@ xmrig::String xmrig::DnsRecord::ip() const if (m_type == AAAA) { buf = new char[45](); - uv_ip6_name(reinterpret_cast(m_data), buf, 45); + uv_ip6_name(reinterpret_cast(m_data), buf, 45); } else { buf = new char[16](); - uv_ip4_name(reinterpret_cast(m_data), buf, 16); + uv_ip4_name(reinterpret_cast(m_data), buf, 16); } return buf; diff --git a/src/base/net/tls/TlsContext.h b/src/base/net/tls/TlsContext.h index 9a9b3cb1..0bb7eec3 100644 --- a/src/base/net/tls/TlsContext.h +++ b/src/base/net/tls/TlsContext.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018 Lee Clagett - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,9 +24,6 @@ #include "base/tools/Object.h" -#include - - using SSL_CTX = struct ssl_ctx_st; @@ -60,6 +57,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_TLSCONTEXT_H */ + +#endif // XMRIG_TLSCONTEXT_H diff --git a/src/base/tools/Object.h b/src/base/tools/Object.h index 00bd9315..f67464ab 100644 --- a/src/base/tools/Object.h +++ b/src/base/tools/Object.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,9 @@ #define XMRIG_OBJECT_H -#include +#include +#include +#include namespace xmrig { @@ -41,6 +43,7 @@ namespace xmrig { X &operator=(X &&other) = delete; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_OBJECT_H */ + +#endif // XMRIG_OBJECT_H From 81e87a6931fec9524df4b2988e5c23dd12f31513 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 9 Feb 2023 21:28:39 +0700 Subject: [PATCH 06/87] Revert changes to fix MSVC build. --- src/crypto/ghostrider/ghostrider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index c0fddeac..70138470 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -573,7 +573,7 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct if (helper && (tune[cn_indices[0]].threads == 2) && (tune[cn_indices[1]].threads == 2) && (tune[cn_indices[2]].threads == 2)) { const size_t n = N / 2; - helper->launch_task([av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { + helper->launch_task([n, av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { const uint8_t* input = data; size_t input_size = size; From 667f636c626cd231a3727d624d70c89619723f9e Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 9 Feb 2023 21:45:50 +0700 Subject: [PATCH 07/87] Fixed DnsUvBackend storage cleanup. --- src/base/net/dns/DnsUvBackend.cpp | 29 ++++++++++++++++++----------- src/base/net/tools/Storage.h | 9 ++++++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/base/net/dns/DnsUvBackend.cpp b/src/base/net/dns/DnsUvBackend.cpp index 8de95df5..33f27f95 100644 --- a/src/base/net/dns/DnsUvBackend.cpp +++ b/src/base/net/dns/DnsUvBackend.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,18 +28,19 @@ namespace xmrig { -static Storage* storage = nullptr; -Storage& DnsUvBackend::getStorage() +static Storage *storage = nullptr; + + +Storage &DnsUvBackend::getStorage() { - if (storage == nullptr) storage = new Storage(); + if (storage == nullptr) { + storage = new Storage(); + } + return *storage; } -void DnsUvBackend::releaseStorage() -{ - delete storage; -} static addrinfo hints{}; @@ -61,8 +62,14 @@ xmrig::DnsUvBackend::DnsUvBackend() xmrig::DnsUvBackend::~DnsUvBackend() { - getStorage().release(m_key); - releaseStorage(); + assert(storage); + + storage->release(m_key); + + if (storage->isEmpty()) { + delete storage; + storage = nullptr; + } } diff --git a/src/base/net/tools/Storage.h b/src/base/net/tools/Storage.h index e23e8666..390101c3 100644 --- a/src/base/net/tools/Storage.h +++ b/src/base/net/tools/Storage.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright 2018-2023 SChernykh + * Copyright 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ public: } - inline void *ptr(uintptr_t id) { return reinterpret_cast(id); } + inline TYPE *ptr(uintptr_t id) { return reinterpret_cast(id); } inline TYPE *get(const void *id) const { return get(reinterpret_cast(id)); } @@ -56,6 +56,9 @@ public: return m_data.at(id); } + inline bool isEmpty() const { return m_data.empty(); } + inline size_t size() const { return m_data.size(); } + inline void remove(const void *id) { delete release(reinterpret_cast(id)); } inline void remove(uintptr_t id) { delete release(id); } From 12b9b62ef7a5c99d7bb3188640f8ff003fea3c20 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 19 Feb 2023 09:42:16 +0100 Subject: [PATCH 08/87] Fix for 32-bit clang 15 Don't define `_mm_cvtsi128_si64` and `_mm_cvtsi64_si128` because clang 15 already has them in its headers. --- src/crypto/cn/CryptoNight_x86.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index 434c7363..64622ee4 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -80,7 +80,7 @@ static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *outp void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; -#if defined(__i386__) || defined(_M_IX86) +#if (defined(__i386__) || defined(_M_IX86)) && !(defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 15)) static inline int64_t _mm_cvtsi128_si64(__m128i a) { return ((uint64_t)(uint32_t)_mm_cvtsi128_si32(a) | ((uint64_t)(uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(a, 4)) << 32)); From c62622b114a3f9f4f36579544532c7581910241c Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 26 Feb 2023 22:31:55 +0100 Subject: [PATCH 09/87] Fix: `--randomx-wrmsr=-1` worked only on Intel --- src/crypto/rx/RxConfig.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/crypto/rx/RxConfig.cpp b/src/crypto/rx/RxConfig.cpp index 775c9326..cb50c4d1 100644 --- a/src/crypto/rx/RxConfig.cpp +++ b/src/crypto/rx/RxConfig.cpp @@ -256,10 +256,12 @@ void xmrig::RxConfig::readMSR(const rapidjson::Value &value) return; } - if (value.IsInt() && Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) { + if (value.IsInt()) { const int i = std::min(value.GetInt(), 15); if (i >= 0) { - m_msrPreset.emplace_back(0x1a4, i); + if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) { + m_msrPreset.emplace_back(0x1a4, i); + } } else { m_wrmsr = false; From ebe818a5fbe2ba7ec48572d051979f4f8cac52f5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 7 Mar 2023 23:51:03 +0700 Subject: [PATCH 10/87] Resolved deprecated methods warnings with OpenSSL 3.0. --- src/base/net/tls/TlsContext.cpp | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/base/net/tls/TlsContext.cpp b/src/base/net/tls/TlsContext.cpp index e3621797..54b904ea 100644 --- a/src/base/net/tls/TlsContext.cpp +++ b/src/base/net/tls/TlsContext.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018 Lee Clagett - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +45,7 @@ namespace xmrig { // https://wiki.openssl.org/index.php/Diffie-Hellman_parameters +#if OPENSSL_VERSION_NUMBER < 0x30000000L || defined(LIBRESSL_VERSION_NUMBER) static DH *get_dh2048() { static unsigned char dhp_2048[] = { @@ -96,6 +97,8 @@ static DH *get_dh2048() return dh; } +#endif + } // namespace xmrig @@ -191,6 +194,7 @@ bool xmrig::TlsContext::setCipherSuites(const char *ciphersuites) bool xmrig::TlsContext::setDH(const char *dhparam) { +# if OPENSSL_VERSION_NUMBER < 0x30000000L || defined(LIBRESSL_VERSION_NUMBER) DH *dh = nullptr; if (dhparam != nullptr) { @@ -225,6 +229,34 @@ bool xmrig::TlsContext::setDH(const char *dhparam) return false; } +# else + if (dhparam != nullptr) { + EVP_PKEY *dh = nullptr; + BIO *bio = BIO_new_file(Env::expand(dhparam), "r"); + + if (bio) { + dh = PEM_read_bio_Parameters(bio, nullptr); + BIO_free(bio); + } + + if (!dh) { + LOG_ERR("PEM_read_bio_Parameters(\"%s\") failed.", dhparam); + + return false; + } + + if (SSL_CTX_set0_tmp_dh_pkey(m_ctx, dh) != 1) { + EVP_PKEY_free(dh); + + LOG_ERR("SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed.", dhparam); + + return false; + } + } + else { + SSL_CTX_set_dh_auto(m_ctx, 1); + } +# endif return true; } From 51728b2d5542ea24d0732c7fdacd10522d6aaa73 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Mon, 20 Feb 2023 16:09:19 +0000 Subject: [PATCH 11/87] Fix build with gcc 13 Now some header files are not included transistively with new libstdc++. Bug: https://bugs.gentoo.org/895226 --- src/backend/opencl/runners/OclBaseRunner.cpp | 3 +++ src/backend/opencl/runners/OclCnRunner.cpp | 3 +++ src/backend/opencl/runners/OclKawPowRunner.cpp | 3 +++ src/backend/opencl/runners/OclRxJitRunner.cpp | 3 +++ src/base/net/http/HttpResponse.h | 1 + 5 files changed, 13 insertions(+) diff --git a/src/backend/opencl/runners/OclBaseRunner.cpp b/src/backend/opencl/runners/OclBaseRunner.cpp index 9e2a48a9..33ffda6a 100644 --- a/src/backend/opencl/runners/OclBaseRunner.cpp +++ b/src/backend/opencl/runners/OclBaseRunner.cpp @@ -23,6 +23,9 @@ */ +#include + + #include "backend/opencl/runners/OclBaseRunner.h" #include "backend/opencl/cl/OclSource.h" #include "backend/opencl/OclCache.h" diff --git a/src/backend/opencl/runners/OclCnRunner.cpp b/src/backend/opencl/runners/OclCnRunner.cpp index 9c1e8544..a9a2913a 100644 --- a/src/backend/opencl/runners/OclCnRunner.cpp +++ b/src/backend/opencl/runners/OclCnRunner.cpp @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +#include + + #include "backend/opencl/runners/OclCnRunner.h" #include "backend/opencl/kernels/Cn0Kernel.h" #include "backend/opencl/kernels/Cn1Kernel.h" diff --git a/src/backend/opencl/runners/OclKawPowRunner.cpp b/src/backend/opencl/runners/OclKawPowRunner.cpp index 275e3f9a..f31585d8 100644 --- a/src/backend/opencl/runners/OclKawPowRunner.cpp +++ b/src/backend/opencl/runners/OclKawPowRunner.cpp @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +#include + + #include "backend/opencl/runners/OclKawPowRunner.h" #include "backend/common/Tags.h" #include "3rdparty/libethash/ethash_internal.h" diff --git a/src/backend/opencl/runners/OclRxJitRunner.cpp b/src/backend/opencl/runners/OclRxJitRunner.cpp index c106c94d..26ed52b8 100644 --- a/src/backend/opencl/runners/OclRxJitRunner.cpp +++ b/src/backend/opencl/runners/OclRxJitRunner.cpp @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +#include + + #include "backend/opencl/runners/OclRxJitRunner.h" #include "backend/opencl/cl/rx/randomx_run_gfx803.h" #include "backend/opencl/cl/rx/randomx_run_gfx900.h" diff --git a/src/base/net/http/HttpResponse.h b/src/base/net/http/HttpResponse.h index a6b44997..9e632598 100644 --- a/src/base/net/http/HttpResponse.h +++ b/src/base/net/http/HttpResponse.h @@ -21,6 +21,7 @@ #define XMRIG_HTTPRESPONSE_H +#include #include #include From 7b8ba9ac098a6ccd9eaf9bb046e9a1a5212217b8 Mon Sep 17 00:00:00 2001 From: xmrig Date: Thu, 23 Mar 2023 18:10:43 +0700 Subject: [PATCH 12/87] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d8c769..773a56c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v6.19.1 +- Resolved deprecated methods warnings with OpenSSL 3.0. +- [#3213](https://github.com/xmrig/xmrig/pull/3213) Fixed build with 32-bit clang 15. +- [#3218](https://github.com/xmrig/xmrig/pull/3218) Fixed: `--randomx-wrmsr=-1` worked only on Intel. +- [#3228](https://github.com/xmrig/xmrig/pull/3228) Fixed build with gcc 13. + # v6.19.0 - [#3144](https://github.com/xmrig/xmrig/pull/3144) Update to latest `sse2neon.h`. - [#3161](https://github.com/xmrig/xmrig/pull/3161) MSVC build: enabled parallel compilation. From 6e856ca39c34a6ec256c97d2d0a66acbc52bad5e Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 23 Mar 2023 19:03:09 +0700 Subject: [PATCH 13/87] v6.19.1 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 0e4bbb02..78e3589a 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.1-dev" +#define APP_VERSION "6.19.1" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" From 22118330e30765a7ae038973f12b30f4357720ab Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 23 Mar 2023 20:41:00 +0700 Subject: [PATCH 14/87] v6.19.2-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 78e3589a..7b865fe7 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.1" +#define APP_VERSION "6.19.2-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 19 -#define APP_VER_PATCH 1 +#define APP_VER_PATCH 2 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From bc5c1f7e6533b57dcd4e41bcf2f9d3b1e5e5b15a Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 24 Mar 2023 22:42:26 +0100 Subject: [PATCH 15/87] Fixed parsing of TX_EXTRA_MERGE_MINING_TAG --- src/base/tools/cryptonote/BlockTemplate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index b4fe4bcf..6ce49679 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -269,7 +269,7 @@ bool xmrig::BlockTemplate::parse(bool hashes) case 0x03: // TX_EXTRA_MERGE_MINING_TAG ar_extra(size); setOffset(TX_EXTRA_MERGE_MINING_TAG_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index()); - ar_extra(m_txMergeMiningTag, size + kKeySize); + ar_extra(m_txMergeMiningTag, size); break; default: From 88b0385bfe00f84d584653175a866009f06828a7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 25 Mar 2023 09:42:49 +0000 Subject: [PATCH 16/87] DaemonClient: new X-Hash-Difficulty HTTP header optimization If the caller knows the difficulty of a PoW hash a given nonce yields, it can tell the callee via the X-Hash-Difficulty, which may allow the callee to skip some processing if the difficulty does not meet some criterion. In my case, a merge mining proxy can know it's pointless trying to submit the nonce to a chain with higher difficulty when the nonce only meets the difficulty for a lower difficulty chain. --- src/base/net/stratum/DaemonClient.cpp | 8 ++++++-- src/base/net/stratum/DaemonClient.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 10c04116..6f66dd7c 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -178,7 +178,9 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); # endif - return rpcSend(doc); + std::map headers; + headers.insert({"X-Hash-Difficulty", std::to_string(result.actualDiff())}); + return rpcSend(doc, headers); } @@ -553,9 +555,11 @@ int64_t xmrig::DaemonClient::getBlockTemplate() } -int64_t xmrig::DaemonClient::rpcSend(const rapidjson::Document &doc) +int64_t xmrig::DaemonClient::rpcSend(const rapidjson::Document &doc, const std::map &headers) { FetchRequest req(HTTP_POST, m_pool.host(), m_pool.port(), kJsonRPC, doc, m_pool.isTLS(), isQuiet()); + for (const auto &header: headers) + req.headers.insert(header); fetch(tag(), std::move(req), m_httpListener); return m_sequence++; diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 94d2b973..e852f428 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -86,7 +86,7 @@ private: bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); int64_t getBlockTemplate(); - int64_t rpcSend(const rapidjson::Document &doc); + int64_t rpcSend(const rapidjson::Document &doc, const std::map &headers = {}); void retry(); void send(const char *path); void setState(SocketState state); From d31b3b7c769f08ef6d90ee670f288dcc8f296b55 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 25 Mar 2023 20:56:25 +0700 Subject: [PATCH 17/87] Code style cleanup. --- src/base/net/stratum/DaemonClient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 6f66dd7c..4e311abf 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -180,6 +180,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) std::map headers; headers.insert({"X-Hash-Difficulty", std::to_string(result.actualDiff())}); + return rpcSend(doc, headers); } @@ -558,8 +559,10 @@ int64_t xmrig::DaemonClient::getBlockTemplate() int64_t xmrig::DaemonClient::rpcSend(const rapidjson::Document &doc, const std::map &headers) { FetchRequest req(HTTP_POST, m_pool.host(), m_pool.port(), kJsonRPC, doc, m_pool.isTLS(), isQuiet()); - for (const auto &header: headers) + for (const auto &header : headers) { req.headers.insert(header); + } + fetch(tag(), std::move(req), m_httpListener); return m_sequence++; From 62a3a98e7df46d876832989bf188054ddacf43e0 Mon Sep 17 00:00:00 2001 From: Dmitriy Nikiforov Date: Mon, 27 Mar 2023 18:48:13 +0500 Subject: [PATCH 18/87] fix(cuda): receive CUDA loader error on linux too. --- src/backend/cuda/wrappers/CudaLib.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 00517ae5..8ca11fa5 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -353,13 +353,9 @@ bool xmrig::CudaLib::open() # ifdef XMRIG_OS_LINUX if (m_loader == defaultLoader) { m_loader = Process::location(Process::ExeLocation, m_loader); - } - else { - return false; - } - - if (uv_dlopen(m_loader, &cudaLib) == 0) { - return true; + if (uv_dlopen(m_loader, &cudaLib) == 0) { + return true; + } } # endif From 0f81ab4c6754a6051ed688e2faef6f2ab90359f2 Mon Sep 17 00:00:00 2001 From: Jeremy Chadwick Date: Fri, 31 Mar 2023 20:16:00 -0700 Subject: [PATCH 19/87] Improve .cmd files when run by shortcuts on another drive --- scripts/benchmark_10M.cmd | 2 +- scripts/benchmark_1M.cmd | 2 +- scripts/pool_mine_example.cmd | 2 +- scripts/rtm_ghostrider_example.cmd | 2 +- scripts/solo_mine_example.cmd | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/benchmark_10M.cmd b/scripts/benchmark_10M.cmd index dbbcc78c..833f065c 100644 --- a/scripts/benchmark_10M.cmd +++ b/scripts/benchmark_10M.cmd @@ -1,4 +1,4 @@ @echo off -cd %~dp0 +cd /d "%~dp0" xmrig.exe --bench=10M --submit pause diff --git a/scripts/benchmark_1M.cmd b/scripts/benchmark_1M.cmd index 5d2166d0..b106a1bc 100644 --- a/scripts/benchmark_1M.cmd +++ b/scripts/benchmark_1M.cmd @@ -1,4 +1,4 @@ @echo off -cd %~dp0 +cd /d "%~dp0" xmrig.exe --bench=1M --submit pause diff --git a/scripts/pool_mine_example.cmd b/scripts/pool_mine_example.cmd index 6e35c913..41a42340 100644 --- a/scripts/pool_mine_example.cmd +++ b/scripts/pool_mine_example.cmd @@ -15,6 +15,6 @@ :: Choose pools outside of top 5 to help Monero network be more decentralized! :: Smaller pools also often have smaller fees/payout limits. -cd %~dp0 +cd /d "%~dp0" xmrig.exe -o pool.hashvault.pro:3333 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD -p x pause diff --git a/scripts/rtm_ghostrider_example.cmd b/scripts/rtm_ghostrider_example.cmd index 8b1f4999..85e0a7fb 100644 --- a/scripts/rtm_ghostrider_example.cmd +++ b/scripts/rtm_ghostrider_example.cmd @@ -15,7 +15,7 @@ :: Choose pools outside of top 5 to help Raptoreum network be more decentralized! :: Smaller pools also often have smaller fees/payout limits. -cd %~dp0 +cd /d "%~dp0" :: Use this command line to connect to non-SSL port xmrig.exe -a gr -o raptoreumemporium.com:3008 -u WALLET_ADDRESS -p x :: Or use this command line to connect to an SSL port diff --git a/scripts/solo_mine_example.cmd b/scripts/solo_mine_example.cmd index c925b36d..4cebf567 100644 --- a/scripts/solo_mine_example.cmd +++ b/scripts/solo_mine_example.cmd @@ -11,6 +11,6 @@ :: Mining solo is the best way to help Monero network be more decentralized! :: But you will only get a payout when you find a block which can take more than a year for a single low-end PC. -cd %~dp0 +cd /d "%~dp0" xmrig.exe -o node.xmr.to:18081 -a rx/0 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD --daemon pause From 5e0079f0126f24e7ab136ef8d2baae949f325eca Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 3 Apr 2023 15:01:40 +0200 Subject: [PATCH 20/87] Sync with changes from proxy --- src/base/net/stratum/DaemonClient.cpp | 10 ++++++++-- src/base/net/stratum/Job.cpp | 17 +++++++++++++---- src/base/net/stratum/Job.h | 8 ++++++-- src/base/tools/cryptonote/Signatures.cpp | 18 +++++++++++++++++- src/base/tools/cryptonote/Signatures.h | 2 +- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 4e311abf..9b1cdc42 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -148,6 +148,11 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) memcpy(data + sig_offset * 2, result.sig, 64 * 2); memcpy(data + m_blocktemplate.offset(BlockTemplate::TX_PUBKEY_OFFSET) * 2, result.sig_data, 32 * 2); memcpy(data + m_blocktemplate.offset(BlockTemplate::EPH_PUBLIC_KEY_OFFSET) * 2, result.sig_data + 32 * 2, 32 * 2); + + // Handle view tag for txout_to_tagged_key outputs + if (m_blocktemplate.outputType() == 3) { + Cvt::toHex(data + m_blocktemplate.offset(BlockTemplate::EPH_PUBLIC_KEY_OFFSET) * 2 + 32 * 2, 2, &result.view_tag, 1); + } } if (result.extra_nonce >= 0) { @@ -404,7 +409,8 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) m_blocktemplate.offset(BlockTemplate::TX_PUBKEY_OFFSET) - k, m_blocktemplate.offset(BlockTemplate::TX_EXTRA_NONCE_OFFSET) - k, m_blocktemplate.txExtraNonce().size(), - m_blocktemplate.minerTxMerkleTreeBranch() + m_blocktemplate.minerTxMerkleTreeBranch(), + m_blocktemplate.outputType() == 3 ); # endif @@ -441,7 +447,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) } uint8_t derivation[32]; - if (!generate_key_derivation(m_blocktemplate.blob(BlockTemplate::TX_PUBKEY_OFFSET), secret_viewkey, derivation)) { + if (!generate_key_derivation(m_blocktemplate.blob(BlockTemplate::TX_PUBKEY_OFFSET), secret_viewkey, derivation, nullptr)) { return jobError("Failed to generate key derivation for miner signature."); } diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index 56f5de80..d62e00b1 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -245,6 +245,7 @@ void xmrig::Job::copy(const Job &other) m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset; m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize; m_minerTxMerkleTreeBranch = other.m_minerTxMerkleTreeBranch; + m_hasViewTag = other.m_hasViewTag; # else memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey)); memcpy(m_ephSecretKey, other.m_ephSecretKey, sizeof(m_ephSecretKey)); @@ -300,6 +301,7 @@ void xmrig::Job::move(Job &&other) m_minerTxExtraNonceOffset = other.m_minerTxExtraNonceOffset; m_minerTxExtraNonceSize = other.m_minerTxExtraNonceSize; m_minerTxMerkleTreeBranch = std::move(other.m_minerTxMerkleTreeBranch); + m_hasViewTag = other.m_hasViewTag; # else memcpy(m_ephPublicKey, other.m_ephPublicKey, sizeof(m_ephPublicKey)); memcpy(m_ephSecretKey, other.m_ephSecretKey, sizeof(m_ephSecretKey)); @@ -323,7 +325,7 @@ void xmrig::Job::setSpendSecretKey(const uint8_t *key) } -void xmrig::Job::setMinerTx(const uint8_t *begin, const uint8_t *end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer &minerTxMerkleTreeBranch) +void xmrig::Job::setMinerTx(const uint8_t *begin, const uint8_t *end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer &minerTxMerkleTreeBranch, bool hasViewTag) { m_minerTxPrefix.assign(begin, end); m_minerTxEphPubKeyOffset = minerTxEphPubKeyOffset; @@ -331,6 +333,13 @@ void xmrig::Job::setMinerTx(const uint8_t *begin, const uint8_t *end, size_t min m_minerTxExtraNonceOffset = minerTxExtraNonceOffset; m_minerTxExtraNonceSize = minerTxExtraNonceSize; m_minerTxMerkleTreeBranch = minerTxMerkleTreeBranch; + m_hasViewTag = hasViewTag; +} + + +void xmrig::Job::setViewTagInMinerTx(uint8_t view_tag) +{ + memcpy(m_minerTxPrefix.data() + m_minerTxEphPubKeyOffset + 32, &view_tag, 1); } @@ -340,7 +349,7 @@ void xmrig::Job::setExtraNonceInMinerTx(uint32_t extra_nonce) } -void xmrig::Job::generateSignatureData(String &signatureData) const +void xmrig::Job::generateSignatureData(String &signatureData, uint8_t& view_tag) const { uint8_t* eph_public_key = m_minerTxPrefix.data() + m_minerTxEphPubKeyOffset; uint8_t* txkey_pub = m_minerTxPrefix.data() + m_minerTxPubKeyOffset; @@ -351,14 +360,14 @@ void xmrig::Job::generateSignatureData(String &signatureData) const uint8_t derivation[32]; - generate_key_derivation(m_viewPublicKey, txkey_sec, derivation); + generate_key_derivation(m_viewPublicKey, txkey_sec, derivation, &view_tag); derive_public_key(derivation, 0, m_spendPublicKey, eph_public_key); uint8_t buf[32 * 3] = {}; memcpy(buf, txkey_pub, 32); memcpy(buf + 32, eph_public_key, 32); - generate_key_derivation(txkey_pub, m_viewSecretKey, derivation); + generate_key_derivation(txkey_pub, m_viewSecretKey, derivation, nullptr); derive_secret_key(derivation, 0, m_spendSecretKey, buf + 64); signatureData = Cvt::toHex(buf, sizeof(buf)); diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index e314a266..1ecff369 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -120,10 +120,13 @@ public: # endif # ifdef XMRIG_PROXY_PROJECT + inline bool hasViewTag() const { return m_hasViewTag; } + void setSpendSecretKey(const uint8_t* key); - void setMinerTx(const uint8_t* begin, const uint8_t* end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer& minerTxMerkleTreeBranch); + void setMinerTx(const uint8_t* begin, const uint8_t* end, size_t minerTxEphPubKeyOffset, size_t minerTxPubKeyOffset, size_t minerTxExtraNonceOffset, size_t minerTxExtraNonceSize, const Buffer& minerTxMerkleTreeBranch, bool hasViewTag); + void setViewTagInMinerTx(uint8_t view_tag); void setExtraNonceInMinerTx(uint32_t extra_nonce); - void generateSignatureData(String& signatureData) const; + void generateSignatureData(String& signatureData, uint8_t& view_tag) const; void generateHashingBlob(String& blob) const; # else inline const uint8_t* ephSecretKey() const { return m_hasMinerSignature ? m_ephSecretKey : nullptr; } @@ -178,6 +181,7 @@ private: size_t m_minerTxExtraNonceOffset = 0; size_t m_minerTxExtraNonceSize = 0; Buffer m_minerTxMerkleTreeBranch; + bool m_hasViewTag = false; # else // Miner signatures uint8_t m_ephPublicKey[32]{}; diff --git a/src/base/tools/cryptonote/Signatures.cpp b/src/base/tools/cryptonote/Signatures.cpp index 93571258..13f0c948 100644 --- a/src/base/tools/cryptonote/Signatures.cpp +++ b/src/base/tools/cryptonote/Signatures.cpp @@ -147,7 +147,7 @@ bool check_signature(const uint8_t* prefix_hash, const uint8_t* pub, const uint8 } -bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* derivation) +bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* derivation, uint8_t* view_tag) { ge_p3 point; ge_p2 point2; @@ -162,6 +162,22 @@ bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* ge_p1p1_to_p2(&point2, &point3); ge_tobytes(derivation, &point2); + if (view_tag) { + constexpr uint8_t salt[] = "view_tag"; + constexpr size_t SALT_SIZE = sizeof(salt) - 1; + + uint8_t buf[SALT_SIZE + 32 + 1]; + memcpy(buf, salt, SALT_SIZE); + memcpy(buf + SALT_SIZE, derivation, 32); + + // Assuming output_index == 0 + buf[SALT_SIZE + 32] = 0; + + uint8_t view_tag_full[32]; + xmrig::keccak(buf, sizeof(buf), view_tag_full, sizeof(view_tag_full)); + *view_tag = view_tag_full[0]; + } + return true; } diff --git a/src/base/tools/cryptonote/Signatures.h b/src/base/tools/cryptonote/Signatures.h index 04813313..24ea9ac6 100644 --- a/src/base/tools/cryptonote/Signatures.h +++ b/src/base/tools/cryptonote/Signatures.h @@ -31,7 +31,7 @@ namespace xmrig { void generate_signature(const uint8_t* prefix_hash, const uint8_t* pub, const uint8_t* sec, uint8_t* sig); bool check_signature(const uint8_t* prefix_hash, const uint8_t* pub, const uint8_t* sig); -bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* derivation); +bool generate_key_derivation(const uint8_t* key1, const uint8_t* key2, uint8_t* derivation, uint8_t* view_tag); void derive_secret_key(const uint8_t* derivation, size_t output_index, const uint8_t* base, uint8_t* derived_key); bool derive_public_key(const uint8_t* derivation, size_t output_index, const uint8_t* base, uint8_t* derived_key); From af6647f377265a51ee1d2a20faf4e7a37322a20d Mon Sep 17 00:00:00 2001 From: xmrig Date: Mon, 3 Apr 2023 20:34:35 +0700 Subject: [PATCH 21/87] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 773a56c5..4910d5ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v6.19.2 +- [#3230](https://github.com/xmrig/xmrig/pull/3230) Fixed parsing of `TX_EXTRA_MERGE_MINING_TAG`. +- [#3232](https://github.com/xmrig/xmrig/pull/3232) Added new `X-Hash-Difficulty` HTTP header. +- [#3240](https://github.com/xmrig/xmrig/pull/3240) Improved .cmd files when run by shortcuts on another drive. +- [#3241](https://github.com/xmrig/xmrig/pull/3241) Added view tag calculation (fixes Wownero solo mining issue). + # v6.19.1 - Resolved deprecated methods warnings with OpenSSL 3.0. - [#3213](https://github.com/xmrig/xmrig/pull/3213) Fixed build with 32-bit clang 15. From 038c4fbe3424f2b10200955d58169a7c4edf6dc2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Apr 2023 22:15:40 +0700 Subject: [PATCH 22/87] v6.19.2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 7b865fe7..e013e31a 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.2-dev" +#define APP_VERSION "6.19.2" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" From a2e9b3456d000e212cf3a2dab6ffd402a90535bb Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 4 Apr 2023 00:34:54 +0700 Subject: [PATCH 23/87] v6.19.3-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index e013e31a..68d96fde 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.2" +#define APP_VERSION "6.19.3-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 19 -#define APP_VER_PATCH 2 +#define APP_VER_PATCH 3 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From c4e136314815f6892136f6be604121143fed10f9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 7 Apr 2023 23:35:05 +0700 Subject: [PATCH 24/87] #3245 Improved algorithm negotiation for donation rounds by sending extra information about current mining job. --- src/crypto/kawpow/KPHash.h | 18 +++++------ src/net/Network.cpp | 7 ++--- src/net/Network.h | 8 ++--- src/net/strategies/DonateStrategy.cpp | 45 ++++++++++++++++++--------- src/net/strategies/DonateStrategy.h | 21 +++++++------ 5 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/crypto/kawpow/KPHash.h b/src/crypto/kawpow/KPHash.h index 15bb1902..7ce2d75e 100644 --- a/src/crypto/kawpow/KPHash.h +++ b/src/crypto/kawpow/KPHash.h @@ -7,8 +7,8 @@ * Copyright 2017-2019 XMR-Stak , * Copyright 2018 Lee Clagett * Copyright 2018-2019 tevador - * Copyright 2018-2020 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright 2018-2023 SChernykh + * Copyright 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ #define XMRIG_KP_HASH_H -#include +#include namespace xmrig @@ -43,16 +43,16 @@ class KPHash public: static constexpr uint32_t EPOCH_LENGTH = 7500; static constexpr uint32_t PERIOD_LENGTH = 3; - static constexpr int CNT_CACHE = 11; - static constexpr int CNT_MATH = 18; - static constexpr uint32_t REGS = 32; - static constexpr uint32_t LANES = 16; + static constexpr int CNT_CACHE = 11; + static constexpr int CNT_MATH = 18; + static constexpr uint32_t REGS = 32; + static constexpr uint32_t LANES = 16; static void calculate(const KPCache& light_cache, uint32_t block_height, const uint8_t (&header_hash)[32], uint64_t nonce, uint32_t (&output)[8], uint32_t (&mix_hash)[8]); }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_KP_HASH_H */ +#endif // XMRIG_KP_HASH_H diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 5b743d5d..a3566242 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 Howard Chu - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -292,8 +292,7 @@ void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) } if (!donate && m_donate) { - m_donate->setAlgo(job.algorithm()); - m_donate->setProxy(client->pool().proxy()); + static_cast(m_donate)->update(client, job); } m_controller->miner()->setJob(job, donate); diff --git a/src/net/Network.h b/src/net/Network.h index 907e6110..b936c0d5 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 Howard Chu - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,7 +89,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_NETWORK_H */ +#endif // XMRIG_NETWORK_H diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 50e98889..03447a01 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2022 SChernykh - * Copyright (c) 2016-2022 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,7 +48,7 @@ static const char *kDonateHost = "donate.v2.xmrig.com"; static const char *kDonateHostTls = "donate.ssl.xmrig.com"; #endif -} /* namespace xmrig */ +} // namespace xmrig xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) : @@ -98,6 +98,17 @@ xmrig::DonateStrategy::~DonateStrategy() } +void xmrig::DonateStrategy::update(IClient *client, const Job &job) +{ + setAlgo(job.algorithm()); + setProxy(client->pool().proxy()); + + m_diff = job.diff(); + m_height = job.height(); + m_seed = job.seed(); +} + + int64_t xmrig::DonateStrategy::submit(const JobResult &result) { return m_proxy ? m_proxy->submit(result) : m_strategy->submit(result); @@ -199,13 +210,13 @@ void xmrig::DonateStrategy::onLogin(IClient *, rapidjson::Document &doc, rapidjs params.AddMember("url", m_pools[0].url().toJSON(), allocator); # endif - setAlgorithms(doc, params); + setParams(doc, params); } void xmrig::DonateStrategy::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) { - setAlgorithms(doc, params); + setParams(doc, params); } @@ -270,12 +281,20 @@ void xmrig::DonateStrategy::idle(double min, double max) } -void xmrig::DonateStrategy::setAlgorithms(rapidjson::Document &doc, rapidjson::Value ¶ms) +void xmrig::DonateStrategy::setJob(IClient *client, const Job &job, const rapidjson::Value ¶ms) +{ + if (isActive()) { + m_listener->onJob(this, client, job, params); + } +} + + +void xmrig::DonateStrategy::setParams(rapidjson::Document &doc, rapidjson::Value ¶ms) { using namespace rapidjson; auto &allocator = doc.GetAllocator(); + auto algorithms = m_controller->miner()->algorithms(); - Algorithms algorithms = m_controller->miner()->algorithms(); const size_t index = static_cast(std::distance(algorithms.begin(), std::find(algorithms.begin(), algorithms.end(), m_algorithm))); if (index > 0 && index < algorithms.size()) { std::swap(algorithms[0], algorithms[index]); @@ -287,14 +306,12 @@ void xmrig::DonateStrategy::setAlgorithms(rapidjson::Document &doc, rapidjson::V algo.PushBack(StringRef(a.name()), allocator); } - params.AddMember("algo", algo, allocator); -} + params.AddMember("algo", algo, allocator); + params.AddMember("diff", m_diff, allocator); + params.AddMember("height", m_height, allocator); - -void xmrig::DonateStrategy::setJob(IClient *client, const Job &job, const rapidjson::Value ¶ms) -{ - if (isActive()) { - m_listener->onJob(this, client, job, params); + if (!m_seed.empty()) { + params.AddMember("seed_hash", Cvt::toHex(m_seed, doc), allocator); } } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 56a0580e..80ec45ca 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2022 SChernykh - * Copyright (c) 2016-2022 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +20,12 @@ #define XMRIG_DONATESTRATEGY_H -#include - - #include "base/kernel/interfaces/IClientListener.h" #include "base/kernel/interfaces/IStrategy.h" #include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/ITimerListener.h" #include "base/net/stratum/Pool.h" -#include "base/tools/Object.h" +#include "base/tools/Buffer.h" namespace xmrig { @@ -36,7 +33,6 @@ namespace xmrig { class Client; class Controller; -class IStrategyListener; class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener @@ -47,6 +43,8 @@ public: DonateStrategy(Controller *controller, IStrategyListener *listener); ~DonateStrategy() override; + void update(IClient *client, const Job &job); + protected: inline bool isActive() const override { return state() == STATE_ACTIVE; } inline IClient *client() const override { return m_proxy ? m_proxy : m_strategy->client(); } @@ -88,13 +86,14 @@ private: IClient *createProxy(); void idle(double min, double max); - void setAlgorithms(rapidjson::Document &doc, rapidjson::Value ¶ms); void setJob(IClient *client, const Job &job, const rapidjson::Value ¶ms); + void setParams(rapidjson::Document &doc, rapidjson::Value ¶ms); void setResult(IClient *client, const SubmitResult &result, const char *error); void setState(State state); Algorithm m_algorithm; bool m_tls = false; + Buffer m_seed; char m_userId[65] = { 0 }; const uint64_t m_donateTime; const uint64_t m_idleTime; @@ -105,12 +104,14 @@ private: State m_state = STATE_NEW; std::vector m_pools; Timer *m_timer = nullptr; + uint64_t m_diff = 0; + uint64_t m_height = 0; uint64_t m_now = 0; uint64_t m_timestamp = 0; }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_DONATESTRATEGY_H */ +#endif // XMRIG_DONATESTRATEGY_H From 7f7fc363e1b28e48340102b963e4ac7b51e0a7b4 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Tue, 18 Apr 2023 21:20:45 +0200 Subject: [PATCH 25/87] Tweaked auto-tuning for Intel CPUs Alder Lake and newer CPUs have exclusive L3 cache and benefit from more threads until L3+L2 is filled. --- src/backend/cpu/platform/HwlocCpuInfo.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index ee2cfca0..d4db2039 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -298,8 +298,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith cores.reserve(m_cores); findByType(cache, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); }); + const bool L3_exclusive = isCacheExclusive(cache); + # ifdef XMRIG_ALGO_GHOSTRIDER - if ((algorithm == Algorithm::GHOSTRIDER_RTM) && (PUs > cores.size()) && (PUs < cores.size() * 2)) { + if ((algorithm == Algorithm::GHOSTRIDER_RTM) && L3_exclusive && (PUs > cores.size()) && (PUs < cores.size() * 2)) { // Don't use E-cores on Alder Lake cores.erase(std::remove_if(cores.begin(), cores.end(), [](hwloc_obj_t c) { return hwloc_bitmap_weight(c->cpuset) == 1; }), cores.end()); @@ -311,7 +313,6 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith # endif size_t L3 = cache->attr->cache.size; - const bool L3_exclusive = isCacheExclusive(cache); size_t L2 = 0; int L2_associativity = 0; size_t extra = 0; @@ -349,6 +350,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith } # ifdef XMRIG_ALGO_RANDOMX + if ((algorithm.family() == Algorithm::RANDOM_X) && L3_exclusive && (PUs > cores.size()) && (PUs < cores.size() * 2)) { + // Use all L3+L2 on latest Intel CPUs with P-cores, E-cores and exclusive L3 cache + cacheHashes = (L3 + L2) / scratchpad; + } if (extra == 0 && algorithm.l2() > 0) { cacheHashes = std::min(std::max(L2 / algorithm.l2(), cores.size()), cacheHashes); } From 5dcbab7e3a784a60eaa7133478e829ba1ccff493 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 21 May 2023 00:39:32 +0200 Subject: [PATCH 26/87] RandomX: optimized program generation --- src/crypto/randomx/aes_hash.cpp | 62 +++++++++----- src/crypto/randomx/intrin_portable.h | 14 ++++ src/crypto/randomx/jit_compiler_a64.cpp | 4 - src/crypto/randomx/jit_compiler_x86.cpp | 106 +++++++++++++----------- 4 files changed, 113 insertions(+), 73 deletions(-) diff --git a/src/crypto/randomx/aes_hash.cpp b/src/crypto/randomx/aes_hash.cpp index ee5989e1..8401d2c8 100644 --- a/src/crypto/randomx/aes_hash.cpp +++ b/src/crypto/randomx/aes_hash.cpp @@ -34,6 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "base/tools/Chrono.h" #include "crypto/randomx/randomx.h" #include "crypto/randomx/soft_aes.h" +#include "crypto/randomx/instruction.hpp" +#include "crypto/randomx/common.hpp" #include "crypto/rx/Profiler.h" #define AES_HASH_1R_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d @@ -165,6 +167,17 @@ void fillAes1Rx4(void *state, size_t outputSize, void *buffer) { template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); +static const rx_vec_i128 inst_mask = []() { + constexpr randomx::Instruction inst{ 0xFF, randomx::RegistersCount - 1, randomx::RegistersCount - 1, 0xFF, 0xFFFFFFFFU }; + + union { + randomx::Instruction mask[2]; + rx_vec_i128 vec; + } result = { inst, inst }; + + return result.vec; +}(); + template void fillAes4Rx4(void *state, size_t outputSize, void *buffer) { const uint8_t* outptr = (uint8_t*)buffer; @@ -187,32 +200,41 @@ void fillAes4Rx4(void *state, size_t outputSize, void *buffer) { state2 = rx_load_vec_i128((rx_vec_i128*)state + 2); state3 = rx_load_vec_i128((rx_vec_i128*)state + 3); - while (outptr < outputEnd) { - state0 = aesdec(state0, key0); - state1 = aesenc(state1, key0); - state2 = aesdec(state2, key4); - state3 = aesenc(state3, key4); - - state0 = aesdec(state0, key1); - state1 = aesenc(state1, key1); - state2 = aesdec(state2, key5); - state3 = aesenc(state3, key5); - - state0 = aesdec(state0, key2); - state1 = aesenc(state1, key2); - state2 = aesdec(state2, key6); - state3 = aesenc(state3, key6); - - state0 = aesdec(state0, key3); - state1 = aesenc(state1, key3); - state2 = aesdec(state2, key7); - state3 = aesenc(state3, key7); +#define TRANSFORM do { \ + state0 = aesdec(state0, key0); \ + state1 = aesenc(state1, key0); \ + state2 = aesdec(state2, key4); \ + state3 = aesenc(state3, key4); \ + state0 = aesdec(state0, key1); \ + state1 = aesenc(state1, key1); \ + state2 = aesdec(state2, key5); \ + state3 = aesenc(state3, key5); \ + state0 = aesdec(state0, key2); \ + state1 = aesenc(state1, key2); \ + state2 = aesdec(state2, key6); \ + state3 = aesenc(state3, key6); \ + state0 = aesdec(state0, key3); \ + state1 = aesenc(state1, key3); \ + state2 = aesdec(state2, key7); \ + state3 = aesenc(state3, key7); \ +} while (0) + for (int i = 0; i < 2; ++i, outptr += 64) { + TRANSFORM; rx_store_vec_i128((rx_vec_i128*)outptr + 0, state0); rx_store_vec_i128((rx_vec_i128*)outptr + 1, state1); rx_store_vec_i128((rx_vec_i128*)outptr + 2, state2); rx_store_vec_i128((rx_vec_i128*)outptr + 3, state3); + } + const rx_vec_i128 mask = inst_mask; + + while (outptr < outputEnd) { + TRANSFORM; + rx_store_vec_i128((rx_vec_i128*)outptr + 0, rx_and_vec_i128(state0, mask)); + rx_store_vec_i128((rx_vec_i128*)outptr + 1, rx_and_vec_i128(state1, mask)); + rx_store_vec_i128((rx_vec_i128*)outptr + 2, rx_and_vec_i128(state2, mask)); + rx_store_vec_i128((rx_vec_i128*)outptr + 3, rx_and_vec_i128(state3, mask)); outptr += 64; } } diff --git a/src/crypto/randomx/intrin_portable.h b/src/crypto/randomx/intrin_portable.h index df98a543..820bf685 100644 --- a/src/crypto/randomx/intrin_portable.h +++ b/src/crypto/randomx/intrin_portable.h @@ -126,6 +126,7 @@ FORCE_INLINE rx_vec_f128 rx_set1_vec_f128(uint64_t x) { #define rx_xor_vec_f128 _mm_xor_pd #define rx_and_vec_f128 _mm_and_pd +#define rx_and_vec_i128 _mm_and_si128 #define rx_or_vec_f128 _mm_or_pd #ifdef __AES__ @@ -278,6 +279,10 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { return (rx_vec_f128)vec_and(a,b); } +FORCE_INLINE rx_vec_i128 rx_and_vec_i128(rx_vec_i128 a, rx_vec_i128 b) { + return (rx_vec_i128)vec_and(a, b); +} + FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { return (rx_vec_f128)vec_or(a,b); } @@ -444,6 +449,8 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { return vreinterpretq_f64_u8(vandq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b))); } +#define rx_and_vec_i128 vandq_u8 + FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { return vreinterpretq_f64_u8(vorrq_u8(vreinterpretq_u8_f64(a), vreinterpretq_u8_f64(b))); } @@ -635,6 +642,13 @@ FORCE_INLINE rx_vec_f128 rx_and_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { return x; } +FORCE_INLINE rx_vec_i128 rx_and_vec_i128(rx_vec_i128 a, rx_vec_i128 b) { + rx_vec_i128 x; + x.u64[0] = a.u64[0] & b.u64[0]; + x.u64[1] = a.u64[1] & b.u64[1]; + return x; +} + FORCE_INLINE rx_vec_f128 rx_or_vec_f128(rx_vec_f128 a, rx_vec_f128 b) { rx_vec_f128 x; x.i.u64[0] = a.i.u64[0] | b.i.u64[0]; diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index c4f0f002..530658db 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -144,8 +144,6 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con for (uint32_t i = 0; i < program.getSize(); ++i) { Instruction& instr = program(i); - instr.src %= RegistersCount; - instr.dst %= RegistersCount; (this->*engine[instr.opcode])(instr, codePos); } @@ -204,8 +202,6 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration for (uint32_t i = 0; i < program.getSize(); ++i) { Instruction& instr = program(i); - instr.src %= RegistersCount; - instr.dst %= RegistersCount; (this->*engine[instr.opcode])(instr, codePos); } diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 7d2603e5..7f9fb3b6 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -312,11 +312,19 @@ namespace randomx { freePagedMemory(allocatedCode, allocatedSize); } + template + static FORCE_INLINE void prefetch_data(const void* data) { + rx_prefetch_nta(data); + prefetch_data(reinterpret_cast(data) + 64); + } + + template<> FORCE_INLINE void prefetch_data<0>(const void*) {} + + template static FORCE_INLINE void prefetch_data(const T& data) { prefetch_data<(sizeof(T) + 63) / 64>(&data); } + void JitCompilerX86::prepare() { - for (size_t i = 0; i < sizeof(engine); i += 64) - rx_prefetch_nta((const char*)(&engine) + i); - for (size_t i = 0; i < sizeof(RandomX_CurrentConfig); i += 64) - rx_prefetch_nta((const char*)(&RandomX_CurrentConfig) + i); + prefetch_data(engine); + prefetch_data(RandomX_CurrentConfig); } void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) { @@ -748,7 +756,7 @@ namespace randomx { template void JitCompilerX86::genAddressReg(const Instruction& instr, const uint32_t src, uint8_t* code, uint32_t& codePos); FORCE_INLINE void JitCompilerX86::genAddressRegDst(const Instruction& instr, uint8_t* code, uint32_t& codePos) { - const uint32_t dst = static_cast(instr.dst % RegistersCount) << 16; + const uint32_t dst = static_cast(instr.dst) << 16; *(uint32_t*)(code + codePos) = 0x24808d41 + dst; codePos += (dst == (RegisterNeedsSib << 16)) ? 4 : 3; @@ -768,8 +776,8 @@ namespace randomx { uint32_t pos = codePos; uint8_t* const p = code + pos; - const uint32_t dst = instr.dst % RegistersCount; - const uint32_t sib = (instr.getModShift() << 6) | ((instr.src % RegistersCount) << 3) | dst; + const uint32_t dst = instr.dst; + const uint32_t sib = (instr.getModShift() << 6) | (instr.src << 3) | dst; uint32_t k = 0x048d4f + (dst << 19); if (dst == RegisterNeedsDisplacement) @@ -788,8 +796,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -809,8 +817,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; if (src != dst) { *(uint32_t*)(p + pos) = 0xc02b4d + (dst << 19) + (src << 16); @@ -830,8 +838,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -851,8 +859,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; if (src != dst) { emit32(0xc0af0f4d + ((dst * 8 + src) << 24), p, pos); @@ -871,8 +879,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -892,8 +900,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; *(uint32_t*)(p + pos) = 0xc08b49 + (dst << 16); *(uint32_t*)(p + pos + 3) = 0xe0f749 + (src << 16); @@ -908,8 +916,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; *(uint32_t*)(p + pos) = 0xC4D08B49 + (dst << 16); *(uint32_t*)(p + pos + 4) = 0xC0F6FB42 + (dst << 27) + (src << 24); @@ -923,8 +931,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -947,8 +955,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -970,8 +978,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; *(uint64_t*)(p + pos) = 0x8b4ce8f749c08b49ull + (dst << 16) + (src << 40); pos += 8; @@ -985,8 +993,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -1011,7 +1019,7 @@ namespace randomx { uint64_t divisor = instr.getImm32(); if (!isZeroOrPowerOf2(divisor)) { - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t dst = instr.dst; const uint64_t reciprocal = randomx_reciprocal_fast(divisor); if (imul_rcp_storage_used < 16) { @@ -1040,7 +1048,7 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t dst = instr.dst; *(uint32_t*)(p + pos) = 0xd8f749 + (dst << 16); pos += 3; @@ -1052,8 +1060,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { *(uint32_t*)(p + pos) = 0xc0334d + (((dst << 3) + src) << 16); @@ -1073,8 +1081,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { genAddressReg(instr, src, p, pos); @@ -1094,8 +1102,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { *(uint64_t*)(p + pos) = 0xc8d349c88b41ull + (src << 16) + (dst << 40); @@ -1115,8 +1123,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t src = instr.src % RegistersCount; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t src = instr.src; + const uint64_t dst = instr.dst; if (src != dst) { *(uint64_t*)(p + pos) = 0xc0d349c88b41ull + (src << 16) + (dst << 40); @@ -1136,8 +1144,8 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint32_t src = instr.src % RegistersCount; - const uint32_t dst = instr.dst % RegistersCount; + const uint32_t src = instr.src; + const uint32_t dst = instr.dst; if (src != dst) { *(uint32_t*)(p + pos) = 0xc0874d + (((dst << 3) + src) << 16); @@ -1153,7 +1161,7 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const uint64_t dst = instr.dst % RegistersCount; + const uint64_t dst = instr.dst; *(uint64_t*)(p + pos) = 0x01c0c60f66ull + (((dst << 3) + dst) << 24); pos += 5; @@ -1182,7 +1190,7 @@ namespace randomx { prevFPOperation = pos; - const uint32_t src = instr.src % RegistersCount; + const uint32_t src = instr.src; const uint32_t dst = instr.dst % RegisterCountFlt; genAddressReg(instr, src, p, pos); @@ -1214,7 +1222,7 @@ namespace randomx { prevFPOperation = pos; - const uint32_t src = instr.src % RegistersCount; + const uint32_t src = instr.src; const uint32_t dst = instr.dst % RegisterCountFlt; genAddressReg(instr, src, p, pos); @@ -1257,7 +1265,7 @@ namespace randomx { prevFPOperation = pos; - const uint32_t src = instr.src % RegistersCount; + const uint32_t src = instr.src; const uint64_t dst = instr.dst % RegisterCountFlt; genAddressReg(instr, src, p, pos); @@ -1307,7 +1315,7 @@ namespace randomx { uint32_t pos = codePos; prevCFROUND = pos; - const uint32_t src = instr.src % RegistersCount; + const uint32_t src = instr.src; *(uint32_t*)(p + pos) = 0x00C08B49 + (src << 16); const int rotate = (static_cast(instr.getImm32() & 63) - 2) & 63; @@ -1343,7 +1351,7 @@ namespace randomx { uint32_t pos = codePos; prevCFROUND = pos; - const uint64_t src = instr.src % RegistersCount; + const uint64_t src = instr.src; const uint64_t rotate = (static_cast(instr.getImm32() & 63) - 2) & 63; *(uint64_t*)(p + pos) = 0xC0F0FBC3C4ULL | (src << 32) | (rotate << 40); @@ -1367,7 +1375,7 @@ namespace randomx { uint8_t* const p = code; uint32_t pos = codePos; - const int reg = instr.dst % RegistersCount; + const int reg = instr.dst; int32_t jmp_offset = registerUsage[reg]; // if it jumps over the previous FP instruction that uses rounding, treat it as if FP instruction happened now @@ -1426,7 +1434,7 @@ namespace randomx { uint32_t pos = codePos; genAddressRegDst(instr, p, pos); - emit32(0x0604894c + (static_cast(instr.src % RegistersCount) << 19), p, pos); + emit32(0x0604894c + (static_cast(instr.src) << 19), p, pos); codePos = pos; } From 1252a4710e638965783343a14772659790a6b0d8 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Tue, 23 May 2023 14:37:09 +0200 Subject: [PATCH 27/87] RandomX: fixed undefined behavior Using an inactive member of a `union` is an undefined behavior in C++ --- src/crypto/randomx/aes_hash.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/crypto/randomx/aes_hash.cpp b/src/crypto/randomx/aes_hash.cpp index 8401d2c8..38eb4d64 100644 --- a/src/crypto/randomx/aes_hash.cpp +++ b/src/crypto/randomx/aes_hash.cpp @@ -167,16 +167,8 @@ void fillAes1Rx4(void *state, size_t outputSize, void *buffer) { template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); template void fillAes1Rx4(void *state, size_t outputSize, void *buffer); -static const rx_vec_i128 inst_mask = []() { - constexpr randomx::Instruction inst{ 0xFF, randomx::RegistersCount - 1, randomx::RegistersCount - 1, 0xFF, 0xFFFFFFFFU }; - - union { - randomx::Instruction mask[2]; - rx_vec_i128 vec; - } result = { inst, inst }; - - return result.vec; -}(); +static constexpr randomx::Instruction inst{ 0xFF, 7, 7, 0xFF, 0xFFFFFFFFU }; +alignas(16) static const randomx::Instruction inst_mask[2] = { inst, inst }; template void fillAes4Rx4(void *state, size_t outputSize, void *buffer) { @@ -227,7 +219,8 @@ void fillAes4Rx4(void *state, size_t outputSize, void *buffer) { rx_store_vec_i128((rx_vec_i128*)outptr + 3, state3); } - const rx_vec_i128 mask = inst_mask; + static_assert(sizeof(inst_mask) == sizeof(rx_vec_i128), "Incorrect inst_mask size"); + const rx_vec_i128 mask = *reinterpret_cast(inst_mask); while (outptr < outputEnd) { TRANSFORM; From 548fbb9f711b2817ad2386f9c4b8020ba3a28ec5 Mon Sep 17 00:00:00 2001 From: Tony Butler Date: Wed, 22 Dec 2021 05:17:08 -0700 Subject: [PATCH 28/87] Add API rebind polling --- src/base/api/Api.cpp | 14 ++++++++++++++ src/base/api/Api.h | 2 ++ src/base/api/Httpd.h | 1 + src/net/Network.cpp | 3 +++ 4 files changed, 20 insertions(+) diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index 54666efd..a7246b9f 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -123,6 +123,20 @@ void xmrig::Api::stop() } +void xmrig::Api::tick() +{ +# ifdef XMRIG_FEATURE_HTTP + if (!m_base->config()->http().isEnabled() || m_httpd->isBound()) { + return; + } + if (++m_ticks % 10 == 0) { + m_ticks = 0; + m_httpd->start(); + } +# endif +} + + void xmrig::Api::onConfigChanged(Config *config, Config *previousConfig) { if (config->apiId() != previousConfig->apiId()) { diff --git a/src/base/api/Api.h b/src/base/api/Api.h index c56e29ee..685b56ff 100644 --- a/src/base/api/Api.h +++ b/src/base/api/Api.h @@ -54,6 +54,7 @@ public: void request(const HttpData &req); void start(); void stop(); + void tick(); protected: void onConfigChanged(Config *config, Config *previousConfig) override; @@ -67,6 +68,7 @@ private: char m_id[32]{}; String m_workerId; const uint64_t m_timestamp; + uint8_t m_ticks; Httpd *m_httpd = nullptr; std::vector m_listeners; }; diff --git a/src/base/api/Httpd.h b/src/base/api/Httpd.h index 188646f5..fe8cb914 100644 --- a/src/base/api/Httpd.h +++ b/src/base/api/Httpd.h @@ -48,6 +48,7 @@ public: bool start(); void stop(); + inline const bool isBound() const { return m_server != nullptr; } protected: void onConfigChanged(Config *config, Config *previousConfig) override; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index a3566242..841dd316 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -308,6 +308,9 @@ void xmrig::Network::tick() if (m_donate) { m_donate->tick(now); } +#ifdef XMRIG_FEATURE_API + m_controller->api()->tick(); +#endif } From 826e23b4c4ba72ddd06c6476e1d9c1050402def9 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 26 May 2023 12:46:59 +0200 Subject: [PATCH 29/87] Fixed `jccErratum` list --- src/backend/cpu/platform/BasicCpuInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index 0680d1bf..3ddce3e7 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -296,7 +296,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : // Affected CPU models and stepping numbers are taken from https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf m_jccErratum = ((model == 0x4E) && (stepping == 0x3)) || - ((model == 0x55) && (stepping == 0x4)) || + ((model == 0x55) && ((stepping == 0x4) || (stepping == 0x7))) || ((model == 0x5E) && (stepping == 0x3)) || ((model == 0x8E) && (stepping >= 0x9) && (stepping <= 0xC)) || ((model == 0x9E) && (stepping >= 0x9) && (stepping <= 0xD)) || From af87369e4f15c256e247da54a72c0cfec45ddf68 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 2 Jun 2023 09:34:26 +0200 Subject: [PATCH 30/87] Updated example scripts - Hashvault is top 1 pool now, so changed it to a smaller pool - node.xmr.to doesn't exist anymore --- scripts/pool_mine_example.cmd | 2 +- scripts/solo_mine_example.cmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/pool_mine_example.cmd b/scripts/pool_mine_example.cmd index 41a42340..38f93e2e 100644 --- a/scripts/pool_mine_example.cmd +++ b/scripts/pool_mine_example.cmd @@ -16,5 +16,5 @@ :: Smaller pools also often have smaller fees/payout limits. cd /d "%~dp0" -xmrig.exe -o pool.hashvault.pro:3333 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD -p x +xmrig.exe -o xmrpool.eu:3333 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD -p x pause diff --git a/scripts/solo_mine_example.cmd b/scripts/solo_mine_example.cmd index 4cebf567..ab912293 100644 --- a/scripts/solo_mine_example.cmd +++ b/scripts/solo_mine_example.cmd @@ -12,5 +12,5 @@ :: But you will only get a payout when you find a block which can take more than a year for a single low-end PC. cd /d "%~dp0" -xmrig.exe -o node.xmr.to:18081 -a rx/0 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD --daemon +xmrig.exe -o YOUR_NODE_IP:18081 -a rx/0 -u 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD --daemon pause From e6bf4c00779a81c10e857505daefd8bc1fc2936b Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 2 Jun 2023 22:12:18 +0700 Subject: [PATCH 31/87] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4910d5ef..4206cd54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v6.19.3 +- [#3245](https://github.com/xmrig/xmrig/issues/3245) Improved algorithm negotiation for donation rounds by sending extra information about current mining job. +- [#3254](https://github.com/xmrig/xmrig/pull/3254) Tweaked auto-tuning for Intel CPUs. +- [#3271](https://github.com/xmrig/xmrig/pull/3271) RandomX: optimized program generation. +- [#3273](https://github.com/xmrig/xmrig/pull/3273) RandomX: fixed undefined behavior. +- [#3275](https://github.com/xmrig/xmrig/pull/3275) RandomX: fixed `jccErratum` list. +- [#3280](https://github.com/xmrig/xmrig/pull/3280) Updated example scripts. + # v6.19.2 - [#3230](https://github.com/xmrig/xmrig/pull/3230) Fixed parsing of `TX_EXTRA_MERGE_MINING_TAG`. - [#3232](https://github.com/xmrig/xmrig/pull/3232) Added new `X-Hash-Difficulty` HTTP header. From 0bc87345c4a0c796557a90885c9a17d3cd9d4c08 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 3 Jun 2023 19:59:18 +0700 Subject: [PATCH 32/87] v6.19.3 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 68d96fde..43bde712 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.3-dev" +#define APP_VERSION "6.19.3" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" From cdd5dff3377efa9f46f9cd9adfd9dd483c789513 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 3 Jun 2023 21:14:26 +0700 Subject: [PATCH 33/87] v6.19.4-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 43bde712..c9f41de3 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.3" +#define APP_VERSION "6.19.4-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 19 -#define APP_VER_PATCH 3 +#define APP_VER_PATCH 4 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 055db83142fca64fea5b992a5ddd9453e65a5d78 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 4 Jun 2023 19:36:53 +0700 Subject: [PATCH 34/87] Added new ARM CPU names. --- src/backend/cpu/platform/lscpu_arm.cpp | 112 ++++++++++++++++++------- 1 file changed, 84 insertions(+), 28 deletions(-) diff --git a/src/backend/cpu/platform/lscpu_arm.cpp b/src/backend/cpu/platform/lscpu_arm.cpp index d632ac49..7616632b 100644 --- a/src/backend/cpu/platform/lscpu_arm.cpp +++ b/src/backend/cpu/platform/lscpu_arm.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018 Riku Voipio - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "base/tools/String.h" #include "3rdparty/fmt/core.h" @@ -84,6 +83,7 @@ static const id_part arm_part[] = { { 0xc27, "Cortex-M7" }, { 0xc60, "Cortex-M0+" }, { 0xd01, "Cortex-A32" }, + { 0xd02, "Cortex-A34" }, { 0xd03, "Cortex-A53" }, { 0xd04, "Cortex-A35" }, { 0xd05, "Cortex-A55" }, @@ -97,40 +97,60 @@ static const id_part arm_part[] = { { 0xd0d, "Cortex-A77" }, { 0xd0e, "Cortex-A76AE" }, { 0xd13, "Cortex-R52" }, + { 0xd15, "Cortex-R82" }, { 0xd20, "Cortex-M23" }, { 0xd21, "Cortex-M33" }, + { 0xd40, "Neoverse-V1" }, { 0xd41, "Cortex-A78" }, { 0xd42, "Cortex-A78AE" }, + { 0xd43, "Cortex-A65AE" }, + { 0xd44, "Cortex-X1" }, + { 0xd46, "Cortex-A510" }, + { 0xd47, "Cortex-A710" }, + { 0xd48, "Cortex-X2" }, + { 0xd49, "Neoverse-N2" }, { 0xd4a, "Neoverse-E1" }, { 0xd4b, "Cortex-A78C" }, - { -1, nullptr }, + { 0xd4c, "Cortex-X1C" }, + { 0xd4d, "Cortex-A715" }, + { 0xd4e, "Cortex-X3" }, + { 0xd4f, "Neoverse-V2" }, + { -1, nullptr } }; static const id_part brcm_part[] = { - { 0x0f, "Brahma B15" }, - { 0x100, "Brahma B53" }, + { 0x0f, "Brahma-B15" }, + { 0x100, "Brahma-B53" }, { 0x516, "ThunderX2" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part dec_part[] = { { 0xa10, "SA110" }, { 0xa11, "SA1100" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part cavium_part[] = { { 0x0a0, "ThunderX" }, - { 0x0a1, "ThunderX 88XX" }, - { 0x0a2, "ThunderX 81XX" }, - { 0x0a3, "ThunderX 83XX" }, - { 0x0af, "ThunderX2 99xx" }, - { -1, nullptr }, + { 0x0a1, "ThunderX-88XX" }, + { 0x0a2, "ThunderX-81XX" }, + { 0x0a3, "ThunderX-83XX" }, + { 0x0af, "ThunderX2-99xx" }, + { 0x0b0, "OcteonTX2" }, + { 0x0b1, "OcteonTX2-98XX" }, + { 0x0b2, "OcteonTX2-96XX" }, + { 0x0b3, "OcteonTX2-95XX" }, + { 0x0b4, "OcteonTX2-95XXN" }, + { 0x0b5, "OcteonTX2-95XXMM" }, + { 0x0b6, "OcteonTX2-95XXO" }, + { 0x0b8, "ThunderX3-T110" }, + { -1, nullptr } }; static const id_part apm_part[] = { { 0x000, "X-Gene" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part qcom_part[] = { @@ -141,36 +161,43 @@ static const id_part qcom_part[] = { { 0x201, "Kryo" }, { 0x205, "Kryo" }, { 0x211, "Kryo" }, - { 0x800, "Falkor V1/Kryo" }, - { 0x801, "Kryo V2" }, + { 0x800, "Falkor-V1/Kryo" }, + { 0x801, "Kryo-V2" }, + { 0x802, "Kryo-3XX-Gold" }, + { 0x803, "Kryo-3XX-Silver" }, + { 0x804, "Kryo-4XX-Gold" }, + { 0x805, "Kryo-4XX-Silver" }, { 0xc00, "Falkor" }, { 0xc01, "Saphira" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part samsung_part[] = { { 0x001, "exynos-m1" }, - { -1, nullptr }, + { 0x002, "exynos-m3" }, + { 0x003, "exynos-m4" }, + { 0x004, "exynos-m5" }, + { -1, nullptr } }; static const id_part nvidia_part[] = { { 0x000, "Denver" }, { 0x003, "Denver 2" }, { 0x004, "Carmel" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part marvell_part[] = { - { 0x131, "Feroceon 88FR131" }, + { 0x131, "Feroceon-88FR131" }, { 0x581, "PJ4/PJ4b" }, { 0x584, "PJ4B-MP" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part faraday_part[] = { { 0x526, "FA526" }, { 0x626, "FA626" }, - { -1, nullptr }, + { -1, nullptr } }; static const id_part intel_part[] = { @@ -195,23 +222,50 @@ static const id_part intel_part[] = { { 0x689, "PXA31x" }, { 0xb11, "SA1110" }, { 0xc12, "IPX1200" }, - { -1, nullptr }, + { -1, nullptr } }; static const struct id_part fujitsu_part[] = { { 0x001, "A64FX" }, - { -1, "unknown" }, + { -1, nullptr } }; static const id_part hisi_part[] = { - { 0xd01, "Kunpeng-920" }, /* aka tsv110 */ - { -1, nullptr }, + { 0xd01, "Kunpeng-920" }, /* aka tsv110 */ + { 0xd40, "Cortex-A76" }, /* HiSilicon uses this ID though advertises A76 */ + { -1, nullptr } }; static const id_part apple_part[] = { { 0x022, "M1" }, { 0x023, "M1" }, - { -1, nullptr }, + { 0x024, "M1-Pro" }, + { 0x025, "M1-Pro" }, + { 0x028, "M1-Max" }, + { 0x029, "M1-Max" }, + { 0x032, "M2" }, + { 0x033, "M2" }, + { 0x034, "M2-Pro" }, + { 0x035, "M2-Pro" }, + { 0x038, "M2-Max" }, + { 0x039, "M2-Max" }, + { -1, nullptr } +}; + + +static const struct id_part ft_part[] = { + { 0x660, "FTC660" }, + { 0x661, "FTC661" }, + { 0x662, "FTC662" }, + { 0x663, "FTC663" }, + { -1, nullptr } +}; + + +static const struct id_part ampere_part[] = { + { 0xac3, "Ampere-1" }, + { 0xac4, "Ampere-1a" }, + { -1, nullptr } }; @@ -229,7 +283,9 @@ static const hw_impl hw_implementer[] = { { 0x56, marvell_part, "Marvell" }, { 0x61, apple_part, "Apple" }, { 0x66, faraday_part, "Faraday" }, - { 0x69, intel_part, "Intel" } + { 0x69, intel_part, "Intel" }, + { 0x70, ft_part, "Phytium" }, + { 0xc0, ampere_part, "Ampere" } }; From 6dbd46a891e9cd0b7554b185222abb23046c5d8c Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 4 Jun 2023 20:32:05 +0700 Subject: [PATCH 35/87] Added new CMake options ARM_V8 and ARM_V7. --- CMakeLists.txt | 3 ++- cmake/cpu.cmake | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a44e672b..d37734ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,8 @@ option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF) option(WITH_DMI "Enable DMI/SMBIOS reader" ON) option(BUILD_STATIC "Build static binary" OFF) -option(ARM_TARGET "Force use specific ARM target 8 or 7" 0) +option(ARM_V8 "Force ARMv8 (64 bit) architecture, use with caution if automatic detection fails, but you sure it may work" OFF) +option(ARM_V7 "Force ARMv7 (32 bit) architecture, use with caution if automatic detection fails, but you sure it may work" OFF) option(HWLOC_DEBUG "Enable hwloc debug helpers and log" OFF) diff --git a/cmake/cpu.cmake b/cmake/cpu.cmake index cbcd8b01..cdc35f10 100644 --- a/cmake/cpu.cmake +++ b/cmake/cpu.cmake @@ -29,6 +29,12 @@ else() set(WITH_VAES OFF) endif() +if (ARM_V8) + set(ARM_TARGET 8) +elseif (ARM_V7) + set(ARM_TARGET 7) +endif() + if (NOT ARM_TARGET) if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|armv8-a)$") set(ARM_TARGET 8) From 554b60966bdbde1d426a7689eb871c711d9e7666 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2023 02:30:10 +0700 Subject: [PATCH 36/87] Fixed compatibility with hwloc 1.11. --- src/backend/cpu/platform/HwlocCpuInfo.cpp | 26 +++++++++++------------ src/backend/cpu/platform/HwlocCpuInfo.h | 4 ++-- src/crypto/ghostrider/ghostrider.cpp | 20 ++++++++++++++--- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index d4db2039..95753ae2 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,27 +36,25 @@ #include "base/io/log/Log.h" +#if HWLOC_API_VERSION < 0x20000 +static inline int hwloc_obj_type_is_cache(hwloc_obj_type_t type) +{ + return type == HWLOC_OBJ_CACHE; +} +#endif + + namespace xmrig { uint32_t HwlocCpuInfo::m_features = 0; -static inline bool isCacheObject(hwloc_obj_t obj) -{ -# if HWLOC_API_VERSION >= 0x20000 - return hwloc_obj_type_is_cache(obj->type); -# else - return obj->type == HWLOC_OBJ_CACHE; -# endif -} - - template static inline void findCache(hwloc_obj_t obj, unsigned min, unsigned max, func lambda) { for (size_t i = 0; i < obj->arity; i++) { - if (isCacheObject(obj->children[i])) { + if (hwloc_obj_type_is_cache(obj->children[i]->type)) { const unsigned depth = obj->children[i]->attr->cache.depth; if (depth < min || depth > max) { continue; @@ -322,7 +320,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith if (cache->attr->cache.depth == 3) { for (size_t i = 0; i < cache->arity; ++i) { hwloc_obj_t l2 = cache->children[i]; - if (!isCacheObject(l2) || l2->attr == nullptr) { + if (!hwloc_obj_type_is_cache(l2->type) || l2->attr == nullptr) { continue; } diff --git a/src/backend/cpu/platform/HwlocCpuInfo.h b/src/backend/cpu/platform/HwlocCpuInfo.h index 390c7d3f..db869184 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.h +++ b/src/backend/cpu/platform/HwlocCpuInfo.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index 70138470..28fdead8 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -47,9 +47,13 @@ #include #ifdef XMRIG_FEATURE_HWLOC -#include "base/kernel/Platform.h" -#include "backend/cpu/platform/HwlocCpuInfo.h" -#include +# include "base/kernel/Platform.h" +# include "backend/cpu/platform/HwlocCpuInfo.h" +# include + +# if HWLOC_API_VERSION < 0x20000 +# define HWLOC_OBJ_L3CACHE HWLOC_OBJ_CACHE +# endif #endif #if defined(XMRIG_ARM) @@ -487,6 +491,12 @@ HelperThread* create_helper_thread(int64_t cpu_index, int priority, const std::v bool is8MB = false; findByType(root, HWLOC_OBJ_L3CACHE, [cpu_index, &is8MB](hwloc_obj_t obj) { +# if HWLOC_API_VERSION < 0x20000 + if (obj->attr->cache.depth != 3) { + return false; + } +# endif + if (!hwloc_bitmap_isset(obj->cpuset, cpu_index)) { return false; } @@ -510,7 +520,11 @@ HelperThread* create_helper_thread(int64_t cpu_index, int priority, const std::v return true; }); +# if HWLOC_API_VERSION >= 0x20000 for (auto obj_type : { HWLOC_OBJ_CORE, HWLOC_OBJ_L1CACHE, HWLOC_OBJ_L2CACHE, HWLOC_OBJ_L3CACHE }) { +# else + for (auto obj_type : { HWLOC_OBJ_CORE, HWLOC_OBJ_CACHE }) { +# endif findByType(root, obj_type, [cpu_index, helper_cpu_set, main_threads_set](hwloc_obj_t obj) { const hwloc_cpuset_t& s = obj->cpuset; if (hwloc_bitmap_isset(s, cpu_index)) { From a2ae17b4c4d09326e7bd8e4f9db9fb0fec40e261 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2023 23:15:58 +0700 Subject: [PATCH 37/87] Code cleanup. --- src/crypto/ghostrider/ghostrider.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index 28fdead8..79241bd3 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -90,7 +90,7 @@ CORE_HASH(14, whirlpool ); #undef CORE_HASH -typedef void (*core_hash_func)(const uint8_t* data, size_t size, uint8_t* output); +using core_hash_func = void (*)(const uint8_t* data, size_t size, uint8_t* output); static const core_hash_func core_hash[15] = { h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11, h12, h13, h14 }; namespace xmrig @@ -169,6 +169,8 @@ static struct AlgoTune struct HelperThread { + XMRIG_DISABLE_COPY_MOVE_DEFAULT(HelperThread) + HelperThread(hwloc_bitmap_t cpu_set, int priority, bool is8MB) : m_cpuSet(cpu_set), m_priority(priority), m_is8MB(is8MB) { uv_mutex_init(&m_mutex); @@ -198,14 +200,17 @@ struct HelperThread struct TaskBase { - virtual ~TaskBase() {} - virtual void run() = 0; + XMRIG_DISABLE_COPY_MOVE(TaskBase) + + TaskBase() = default; + virtual ~TaskBase() = default; + virtual void run() = 0; }; template struct Task : TaskBase { - inline Task(T&& task) : m_task(std::move(task)) + explicit inline Task(T&& task) : m_task(std::move(task)) { static_assert(sizeof(Task) <= 128, "Task struct is too large"); } @@ -223,7 +228,7 @@ struct HelperThread inline void launch_task(T&& task) { uv_mutex_lock(&m_mutex); - new (&m_tasks[m_numTasks++]) Task(std::move(task)); + new (&m_tasks[m_numTasks++]) Task(std::forward(task)); uv_cond_signal(&m_cond); uv_mutex_unlock(&m_mutex); } @@ -294,7 +299,7 @@ void benchmark() hwloc_topology_t topology = reinterpret_cast(Cpu::info())->topology(); hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(topology, thread_index1); - hwloc_obj_t pu2; + hwloc_obj_t pu2 = nullptr; hwloc_get_closest_objs(topology, pu, &pu2, 1); uint32_t thread_index2 = pu2 ? pu2->os_index : thread_index1; @@ -585,9 +590,13 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct uint8_t tmp[64 * N]; if (helper && (tune[cn_indices[0]].threads == 2) && (tune[cn_indices[1]].threads == 2) && (tune[cn_indices[2]].threads == 2)) { - const size_t n = N / 2; + constexpr size_t n = N / 2; + + helper->launch_task([av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { +# ifdef _MSC_VER + constexpr size_t n = N / 2; +# endif - helper->launch_task([n, av, data, size, &ctx_memory, ctx, &cn_indices, &core_indices, &tmp, output, tune]() { const uint8_t* input = data; size_t input_size = size; From c7e541d84f015882d6363972b1641a43337cac01 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2023 00:32:09 +0700 Subject: [PATCH 38/87] Disallow direct use of HwlocCpuInfo class. --- src/backend/cpu/Cpu.h | 8 ++--- src/backend/cpu/interfaces/ICpuInfo.h | 18 +++++++++-- src/backend/cpu/platform/BasicCpuInfo.h | 11 +++---- src/backend/cpu/platform/HwlocCpuInfo.cpp | 7 ---- src/backend/cpu/platform/HwlocCpuInfo.h | 39 +++++++---------------- src/base/kernel/Platform_hwloc.cpp | 15 ++++----- src/crypto/common/VirtualMemory_hwloc.cpp | 11 +++---- src/crypto/ghostrider/ghostrider.cpp | 8 ++--- src/crypto/rx/RxConfig.cpp | 11 ++----- src/crypto/rx/RxConfig.h | 8 ++--- src/crypto/rx/RxNUMAStorage.cpp | 10 +++--- 11 files changed, 61 insertions(+), 85 deletions(-) diff --git a/src/backend/cpu/Cpu.h b/src/backend/cpu/Cpu.h index 186063d3..3067ebcd 100644 --- a/src/backend/cpu/Cpu.h +++ b/src/backend/cpu/Cpu.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ public: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_CPU_H */ +#endif // XMRIG_CPU_H diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index 387f319b..e9d795ce 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,12 @@ #include "crypto/common/Assembly.h" +#ifdef XMRIG_FEATURE_HWLOC +using hwloc_const_bitmap_t = const struct hwloc_bitmap_s *; +using hwloc_topology_t = struct hwloc_topology *; +#endif + + namespace xmrig { @@ -116,10 +122,16 @@ public: virtual size_t threads() const = 0; virtual Vendor vendor() const = 0; virtual uint32_t model() const = 0; + +# ifdef XMRIG_FEATURE_HWLOC + virtual bool membind(hwloc_const_bitmap_t nodeset) = 0; + virtual const std::vector &nodeset() const = 0; + virtual hwloc_topology_t topology() const = 0; +# endif }; -} /* namespace xmrig */ +} // namespace xmrig #endif // XMRIG_CPUINFO_H diff --git a/src/backend/cpu/platform/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h index 9405fa75..f56d5425 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2017-2019 XMR-Stak , - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,11 +72,10 @@ protected: # endif } -protected: Arch m_arch = ARCH_UNKNOWN; bool m_jccErratum = false; char m_brand[64 + 6]{}; - size_t m_threads; + size_t m_threads = 0; std::vector m_units; Vendor m_vendor = VENDOR_UNKNOWN; @@ -94,7 +93,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_BASICCPUINFO_H */ +#endif // XMRIG_BASICCPUINFO_H diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index 95753ae2..f6137c31 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -47,9 +47,6 @@ static inline int hwloc_obj_type_is_cache(hwloc_obj_type_t type) namespace xmrig { -uint32_t HwlocCpuInfo::m_features = 0; - - template static inline void findCache(hwloc_obj_t obj, unsigned min, unsigned max, func lambda) { @@ -172,10 +169,6 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE); if (m_nodes > 1) { - if (hwloc_topology_get_support(m_topology)->membind->set_thisthread_membind) { - m_features |= SET_THISTHREAD_MEMBIND; - } - m_nodeset.reserve(m_nodes); hwloc_obj_t node = nullptr; diff --git a/src/backend/cpu/platform/HwlocCpuInfo.h b/src/backend/cpu/platform/HwlocCpuInfo.h index db869184..a08ea33e 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.h +++ b/src/backend/cpu/platform/HwlocCpuInfo.h @@ -21,12 +21,9 @@ #include "backend/cpu/platform/BasicCpuInfo.h" -#include "base/tools/Object.h" -using hwloc_const_bitmap_t = const struct hwloc_bitmap_s *; -using hwloc_obj_t = struct hwloc_obj *; -using hwloc_topology_t = struct hwloc_topology *; +using hwloc_obj_t = struct hwloc_obj *; namespace xmrig { @@ -37,39 +34,27 @@ class HwlocCpuInfo : public BasicCpuInfo public: XMRIG_DISABLE_COPY_MOVE(HwlocCpuInfo) - - enum Feature : uint32_t { - SET_THISTHREAD_MEMBIND = 1 - }; - - HwlocCpuInfo(); ~HwlocCpuInfo() override; - static inline bool hasFeature(Feature feature) { return m_features & feature; } - - inline const std::vector &nodeset() const { return m_nodeset; } - inline hwloc_topology_t topology() const { return m_topology; } - - bool membind(hwloc_const_bitmap_t nodeset); - protected: + bool membind(hwloc_const_bitmap_t nodeset) override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override; - inline const char *backend() const override { return m_backend; } - inline size_t cores() const override { return m_cores; } - inline size_t L2() const override { return m_cache[2]; } - inline size_t L3() const override { return m_cache[3]; } - inline size_t nodes() const override { return m_nodes; } - inline size_t packages() const override { return m_packages; } + inline const char *backend() const override { return m_backend; } + inline const std::vector &nodeset() const override { return m_nodeset; } + inline hwloc_topology_t topology() const override { return m_topology; } + inline size_t cores() const override { return m_cores; } + inline size_t L2() const override { return m_cache[2]; } + inline size_t L3() const override { return m_cache[3]; } + inline size_t nodes() const override { return m_nodes; } + inline size_t packages() const override { return m_packages; } private: CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const; void processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const; void setThreads(size_t threads); - static uint32_t m_features; - char m_backend[20] = { 0 }; hwloc_topology_t m_topology = nullptr; size_t m_cache[5] = { 0 }; @@ -80,7 +65,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_HWLOCCPUINFO_H */ +#endif // XMRIG_HWLOCCPUINFO_H diff --git a/src/base/kernel/Platform_hwloc.cpp b/src/base/kernel/Platform_hwloc.cpp index 8d9d9f59..219c1742 100644 --- a/src/base/kernel/Platform_hwloc.cpp +++ b/src/base/kernel/Platform_hwloc.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +16,7 @@ * along with this program. If not, see . */ - #include "base/kernel/Platform.h" -#include "backend/cpu/platform/HwlocCpuInfo.h" #include "backend/cpu/Cpu.h" @@ -29,20 +27,21 @@ #ifndef XMRIG_OS_APPLE bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) { - auto cpu = static_cast(Cpu::info()); - hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast(cpu_id)); + auto topology = Cpu::info()->topology(); + auto pu = hwloc_get_pu_obj_by_os_index(topology, static_cast(cpu_id)); if (pu == nullptr) { return false; } - if (hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) >= 0) { + if (hwloc_set_cpubind(topology, pu->cpuset, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) >= 0) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); return true; } - const bool result = (hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD) >= 0); + const bool result = (hwloc_set_cpubind(topology, pu->cpuset, HWLOC_CPUBIND_THREAD) >= 0); std::this_thread::sleep_for(std::chrono::milliseconds(1)); + return result; } #endif diff --git a/src/crypto/common/VirtualMemory_hwloc.cpp b/src/crypto/common/VirtualMemory_hwloc.cpp index d1129008..21b0bd46 100644 --- a/src/crypto/common/VirtualMemory_hwloc.cpp +++ b/src/crypto/common/VirtualMemory_hwloc.cpp @@ -1,8 +1,8 @@ /* XMRig * Copyright (c) 2018 Lee Clagett * Copyright (c) 2018-2019 tevador - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,10 +18,8 @@ * along with this program. If not, see . */ - #include "crypto/common/VirtualMemory.h" #include "backend/cpu/Cpu.h" -#include "backend/cpu/platform/HwlocCpuInfo.h" #include "base/io/log/Log.h" @@ -34,10 +32,9 @@ uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity) return 0; } - auto cpu = static_cast(Cpu::info()); - hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast(affinity)); + auto pu = hwloc_get_pu_obj_by_os_index(Cpu::info()->topology(), static_cast(affinity)); - if (pu == nullptr || !cpu->membind(pu->nodeset)) { + if (pu == nullptr || !Cpu::info()->membind(pu->nodeset)) { LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity); return 0; diff --git a/src/crypto/ghostrider/ghostrider.cpp b/src/crypto/ghostrider/ghostrider.cpp index 79241bd3..25bb44e7 100644 --- a/src/crypto/ghostrider/ghostrider.cpp +++ b/src/crypto/ghostrider/ghostrider.cpp @@ -48,7 +48,6 @@ #ifdef XMRIG_FEATURE_HWLOC # include "base/kernel/Platform.h" -# include "backend/cpu/platform/HwlocCpuInfo.h" # include # if HWLOC_API_VERSION < 0x20000 @@ -243,7 +242,7 @@ struct HelperThread void run() { if (hwloc_bitmap_weight(m_cpuSet) > 0) { - hwloc_topology_t topology = reinterpret_cast(Cpu::info())->topology(); + hwloc_topology_t topology = Cpu::info()->topology(); if (hwloc_set_cpubind(topology, m_cpuSet, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) < 0) { hwloc_set_cpubind(topology, m_cpuSet, HWLOC_CPUBIND_THREAD); } @@ -297,7 +296,7 @@ void benchmark() // Try to avoid CPU core 0 because many system threads use it and can interfere uint32_t thread_index1 = (Cpu::info()->threads() > 2) ? 2 : 0; - hwloc_topology_t topology = reinterpret_cast(Cpu::info())->topology(); + hwloc_topology_t topology = Cpu::info()->topology(); hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(topology, thread_index1); hwloc_obj_t pu2 = nullptr; hwloc_get_closest_objs(topology, pu, &pu2, 1); @@ -490,8 +489,7 @@ HelperThread* create_helper_thread(int64_t cpu_index, int priority, const std::v } if (cpu_index >= 0) { - hwloc_topology_t topology = reinterpret_cast(Cpu::info())->topology(); - hwloc_obj_t root = hwloc_get_root_obj(topology); + hwloc_obj_t root = hwloc_get_root_obj(Cpu::info()->topology()); bool is8MB = false; diff --git a/src/crypto/rx/RxConfig.cpp b/src/crypto/rx/RxConfig.cpp index cb50c4d1..cd196935 100644 --- a/src/crypto/rx/RxConfig.cpp +++ b/src/crypto/rx/RxConfig.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +22,6 @@ #include "base/io/json/Json.h" -#ifdef XMRIG_FEATURE_HWLOC -# include "backend/cpu/platform/HwlocCpuInfo.h" -#endif - - #include #include #include @@ -190,7 +185,7 @@ std::vector xmrig::RxConfig::nodeset() const return m_nodeset; } - return (m_numa && Cpu::info()->nodes() > 1) ? static_cast(Cpu::info())->nodeset() : std::vector(); + return (m_numa && Cpu::info()->nodes() > 1) ? Cpu::info()->nodeset() : std::vector(); } #endif diff --git a/src/crypto/rx/RxConfig.h b/src/crypto/rx/RxConfig.h index e4fb4f89..e8662e4d 100644 --- a/src/crypto/rx/RxConfig.h +++ b/src/crypto/rx/RxConfig.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -123,7 +123,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_RXCONFIG_H */ +#endif // XMRIG_RXCONFIG_H diff --git a/src/crypto/rx/RxNUMAStorage.cpp b/src/crypto/rx/RxNUMAStorage.cpp index b6345a06..cc66d76e 100644 --- a/src/crypto/rx/RxNUMAStorage.cpp +++ b/src/crypto/rx/RxNUMAStorage.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2019 tevador - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,6 @@ #include "crypto/rx/RxNUMAStorage.h" #include "backend/cpu/Cpu.h" -#include "backend/cpu/platform/HwlocCpuInfo.h" #include "base/io/log/Log.h" #include "base/io/log/Tags.h" #include "base/kernel/Platform.h" @@ -45,13 +44,12 @@ static std::mutex mutex; static bool bindToNUMANode(uint32_t nodeId) { - auto cpu = static_cast(Cpu::info()); - hwloc_obj_t node = hwloc_get_numanode_obj_by_os_index(cpu->topology(), nodeId); + auto node = hwloc_get_numanode_obj_by_os_index(Cpu::info()->topology(), nodeId); if (!node) { return false; } - if (cpu->membind(node->nodeset)) { + if (Cpu::info()->membind(node->nodeset)) { Platform::setThreadAffinity(static_cast(hwloc_bitmap_first(node->cpuset))); return true; From 7d7f30701f0e22a0260ec6059a7d2447eb5f4c10 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2023 20:48:56 +0700 Subject: [PATCH 39/87] Code cleanup. --- src/base/api/Api.cpp | 7 ++++--- src/base/api/Api.h | 15 +++++++-------- src/base/api/Httpd.h | 18 +++++++----------- src/net/Network.cpp | 5 +++-- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index a7246b9f..ea78c35e 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -126,9 +126,10 @@ void xmrig::Api::stop() void xmrig::Api::tick() { # ifdef XMRIG_FEATURE_HTTP - if (!m_base->config()->http().isEnabled() || m_httpd->isBound()) { + if (m_httpd->isBound() || !m_base->config()->http().isEnabled()) { return; } + if (++m_ticks % 10 == 0) { m_ticks = 0; m_httpd->start(); diff --git a/src/base/api/Api.h b/src/base/api/Api.h index 685b56ff..7c686ff4 100644 --- a/src/base/api/Api.h +++ b/src/base/api/Api.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,6 @@ #include -#include #include "base/kernel/interfaces/IBaseListener.h" @@ -44,7 +43,7 @@ class Api : public IBaseListener public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(Api) - Api(Base *base); + explicit Api(Base *base); ~Api() override; inline const char *id() const { return m_id; } @@ -66,15 +65,15 @@ private: Base *m_base; char m_id[32]{}; - String m_workerId; const uint64_t m_timestamp; - uint8_t m_ticks; - Httpd *m_httpd = nullptr; + Httpd *m_httpd = nullptr; std::vector m_listeners; + String m_workerId; + uint8_t m_ticks = 0; }; } // namespace xmrig -#endif /* XMRIG_API_H */ +#endif // XMRIG_API_H diff --git a/src/base/api/Httpd.h b/src/base/api/Httpd.h index fe8cb914..e00c8eb5 100644 --- a/src/base/api/Httpd.h +++ b/src/base/api/Httpd.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +22,6 @@ #include "base/kernel/interfaces/IBaseListener.h" #include "base/net/http/HttpListener.h" -#include "base/tools/Object.h" - - -#include -#include namespace xmrig { @@ -43,12 +38,13 @@ class Httpd : public IBaseListener, public IHttpListener public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(Httpd) - Httpd(Base *base); + explicit Httpd(Base *base); ~Httpd() override; + inline bool isBound() const { return m_server != nullptr; } + bool start(); void stop(); - inline const bool isBound() const { return m_server != nullptr; } protected: void onConfigChanged(Config *config, Config *previousConfig) override; @@ -70,7 +66,7 @@ private: }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_HTTPD_H */ +#endif // XMRIG_HTTPD_H diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 841dd316..0ca1914a 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -308,9 +308,10 @@ void xmrig::Network::tick() if (m_donate) { m_donate->tick(now); } -#ifdef XMRIG_FEATURE_API + +# ifdef XMRIG_FEATURE_API m_controller->api()->tick(); -#endif +# endif } From d94d052e6ccca9b0d7aca87afad4f999b2684a63 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 19 Jun 2023 12:32:28 +0200 Subject: [PATCH 40/87] KawPow: fixed data race when building programs `uv_queue_work` can't be called from other threads, only `uv_async_send` is thread-safe. --- .../opencl/runners/tools/OclKawPow.cpp | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/backend/opencl/runners/tools/OclKawPow.cpp b/src/backend/opencl/runners/tools/OclKawPow.cpp index a7e8df3a..4151633c 100644 --- a/src/backend/opencl/runners/tools/OclKawPow.cpp +++ b/src/backend/opencl/runners/tools/OclKawPow.cpp @@ -399,6 +399,9 @@ private: uv_loop_t* m_loop = nullptr; uv_thread_t m_loopThread = {}; uv_async_t m_shutdownAsync = {}; + uv_async_t m_batonAsync = {}; + + std::vector m_batons; static void loop(void* data) { @@ -419,19 +422,37 @@ void KawPowBuilder::build_async(const IOclRunner& runner, uint64_t period, uint3 if (!m_loop) { m_loop = new uv_loop_t{}; uv_loop_init(m_loop); - uv_async_init(m_loop, &m_shutdownAsync, [](uv_async_t* handle) { uv_close(reinterpret_cast(handle), nullptr); }); + + uv_async_init(m_loop, &m_shutdownAsync, [](uv_async_t* handle) + { + KawPowBuilder* builder = reinterpret_cast(handle->data); + uv_close(reinterpret_cast(&builder->m_shutdownAsync), nullptr); + uv_close(reinterpret_cast(&builder->m_batonAsync), nullptr); + }); + + uv_async_init(m_loop, &m_batonAsync, [](uv_async_t* handle) + { + std::vector batons; + { + KawPowBuilder* b = reinterpret_cast(handle->data); + + std::lock_guard lock(b->m_mutex); + batons = std::move(b->m_batons); + } + + for (const KawPowBaton& baton : batons) { + builder.build(baton.runner, baton.period, baton.worksize); + } + }); + + m_shutdownAsync.data = this; + m_batonAsync.data = this; + uv_thread_create(&m_loopThread, loop, this); } - KawPowBaton* baton = new KawPowBaton(runner, period, worksize); - - uv_queue_work(m_loop, &baton->req, - [](uv_work_t* req) { - KawPowBaton* baton = static_cast(req->data); - builder.build(baton->runner, baton->period, baton->worksize); - }, - [](uv_work_t* req, int) { delete static_cast(req->data); } - ); + m_batons.emplace_back(runner, period, worksize); + uv_async_send(&m_batonAsync); } From 6c10cc5a4b6aa3e168cc25760a3fe9d14ffae52b Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sat, 24 Jun 2023 14:37:20 +0200 Subject: [PATCH 41/87] Zephyr coin support Solo mining will require `--coin Zephyr` in command line, or `"coin": "Zephyr",` in `pools` section of config.json --- src/base/crypto/Coin.cpp | 1 + src/base/crypto/Coin.h | 1 + src/base/tools/cryptonote/BlockTemplate.cpp | 46 +++++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/base/crypto/Coin.cpp b/src/base/crypto/Coin.cpp index b63570e1..2508e9cc 100644 --- a/src/base/crypto/Coin.cpp +++ b/src/base/crypto/Coin.cpp @@ -53,6 +53,7 @@ static const CoinInfo coinInfo[] = { { Algorithm::RX_KEVA, "KVA", "Kevacoin", 0, 0, MAGENTA_BG_BOLD(WHITE_BOLD_S " keva ") }, { Algorithm::KAWPOW_RVN, "RVN", "Ravencoin", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " raven ") }, { Algorithm::RX_WOW, "WOW", "Wownero", 300, 100000000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " wownero ") }, + { Algorithm::RX_0, "ZEPH", "Zephyr", 120, 1000000000000, BLUE_BG_BOLD( WHITE_BOLD_S " zephyr ") }, }; diff --git a/src/base/crypto/Coin.h b/src/base/crypto/Coin.h index fbd36371..166618b1 100644 --- a/src/base/crypto/Coin.h +++ b/src/base/crypto/Coin.h @@ -39,6 +39,7 @@ public: KEVA, RAVEN, WOWNERO, + ZEPHYR, MAX }; diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 6ce49679..6f73ec70 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -197,6 +197,11 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_vote); } + if (m_coin == Coin::ZEPHYR) { + uint8_t pricing_record[24]; + ar(pricing_record); + } + // Miner transaction begin // Prefix begin setOffset(MINER_TX_PREFIX_OFFSET, ar.index()); @@ -220,8 +225,8 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_height); ar(m_numOutputs); - // must be 1 output - if (m_numOutputs != 1) { + const uint64_t expected_outputs = (m_coin == Coin::ZEPHYR) ? 2 : 1; + if (m_numOutputs != expected_outputs) { return false; } @@ -237,7 +242,35 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_ephPublicKey, kKeySize); - if (m_outputType == 3) { + if (m_coin == Coin::ZEPHYR) { + if (m_outputType != 2) { + return false; + } + + uint64_t asset_type_len; + ar(asset_type_len); + ar.skip(asset_type_len); + ar(m_viewTag); + + uint64_t amount2; + ar(amount2); + + uint8_t output_type2; + ar(output_type2); + if (output_type2 != 2) { + return false; + } + + Span key2; + ar(key2, kKeySize); + + ar(asset_type_len); + ar.skip(asset_type_len); + + uint8_t view_tag2; + ar(view_tag2); + } + else if (m_outputType == 3) { ar(m_viewTag); } @@ -248,6 +281,8 @@ bool xmrig::BlockTemplate::parse(bool hashes) BlobReader ar_extra(blob(TX_EXTRA_OFFSET), m_extraSize); ar.skip(m_extraSize); + bool pubkey_offset_first = true; + while (ar_extra.index() < m_extraSize) { uint64_t extra_tag = 0; uint64_t size = 0; @@ -256,7 +291,10 @@ bool xmrig::BlockTemplate::parse(bool hashes) switch (extra_tag) { case 0x01: // TX_EXTRA_TAG_PUBKEY - setOffset(TX_PUBKEY_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index()); + if (pubkey_offset_first) { + pubkey_offset_first = false; + setOffset(TX_PUBKEY_OFFSET, offset(TX_EXTRA_OFFSET) + ar_extra.index()); + } ar_extra.skip(kKeySize); break; From cb2f8fd453986f9cbafdc70c7cfb88f418076e45 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sat, 24 Jun 2023 15:15:37 +0200 Subject: [PATCH 42/87] Zephyr solo mining: fix for blocks with transactions --- src/base/tools/cryptonote/BlockTemplate.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 6f73ec70..1926136b 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -315,6 +315,13 @@ bool xmrig::BlockTemplate::parse(bool hashes) } } + if (m_coin == Coin::ZEPHYR) { + uint64_t pricing_record_height, amount_burnt, amount_minted; + ar(pricing_record_height); + ar(amount_burnt); + ar(amount_minted); + } + setOffset(MINER_TX_PREFIX_END_OFFSET, ar.index()); // Prefix end From 09abc812555a018627a291477cc285e3f325758b Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2023 12:37:36 +0700 Subject: [PATCH 43/87] v6.20.0-dev --- CHANGELOG.md | 9 +++++++++ src/version.h | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4206cd54..d81c7c4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v6.20.0 +- Added new ARM CPU names. +- [#2394](https://github.com/xmrig/xmrig/pull/2394) Added new CMake options `ARM_V8` and `ARM_V7`. +- [#2830](https://github.com/xmrig/xmrig/pull/2830) Added API rebind polling. +- [#2927](https://github.com/xmrig/xmrig/pull/2927) Fixed compatibility with hwloc 1.11.x. +- [#3060](https://github.com/xmrig/xmrig/pull/3060) Added x86 to `README.md`. +- [#3236](https://github.com/xmrig/xmrig/pull/3236) Fixed: receive CUDA loader error on Linux too. +- [#3290](https://github.com/xmrig/xmrig/pull/3290) Added [Zephyr](https://www.zephyrprotocol.com/) coin support for solo mining. + # v6.19.3 - [#3245](https://github.com/xmrig/xmrig/issues/3245) Improved algorithm negotiation for donation rounds by sending extra information about current mining job. - [#3254](https://github.com/xmrig/xmrig/pull/3254) Tweaked auto-tuning for Intel CPUs. diff --git a/src/version.h b/src/version.h index c9f41de3..972386b7 100644 --- a/src/version.h +++ b/src/version.h @@ -22,15 +22,15 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.19.4-dev" +#define APP_VERSION "6.20.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 6 -#define APP_VER_MINOR 19 -#define APP_VER_PATCH 4 +#define APP_VER_MINOR 20 +#define APP_VER_PATCH 0 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 2e77faa80ca6b61763987b5ce410998be5bb7a22 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2023 12:42:00 +0700 Subject: [PATCH 44/87] v6.20.0 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 972386b7..36027100 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.20.0-dev" +#define APP_VERSION "6.20.0" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" From e7de104d88a849d0e793d75f79933a10c1847c2c Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2023 18:47:55 +0700 Subject: [PATCH 45/87] v6.20.1-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 36027100..2fc9bf98 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.20.0" +#define APP_VERSION "6.20.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 20 -#define APP_VER_PATCH 0 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 5717e72367b753e9b3ea0efd2c5f9f63d225e688 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 17 Jul 2023 09:49:10 +0200 Subject: [PATCH 46/87] Enabled keepalive for Windows (>= Vista) --- src/base/kernel/Platform.h | 2 ++ src/base/kernel/Platform_mac.cpp | 6 ++++++ src/base/kernel/Platform_unix.cpp | 6 ++++++ src/base/kernel/Platform_win.cpp | 6 ++++++ src/base/net/stratum/Client.cpp | 7 ++++--- src/base/net/stratum/DaemonClient.cpp | 7 ++++--- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/base/kernel/Platform.h b/src/base/kernel/Platform.h index 04c212e6..b63a65fb 100644 --- a/src/base/kernel/Platform.h +++ b/src/base/kernel/Platform.h @@ -49,6 +49,8 @@ public: static inline bool isUserActive(uint64_t ms) { return idleTime() < ms; } static inline const String &userAgent() { return m_userAgent; } + static bool hasKeepalive(); + static bool isOnBatteryPower(); static uint64_t idleTime(); diff --git a/src/base/kernel/Platform_mac.cpp b/src/base/kernel/Platform_mac.cpp index d07e925d..8420d128 100644 --- a/src/base/kernel/Platform_mac.cpp +++ b/src/base/kernel/Platform_mac.cpp @@ -55,6 +55,12 @@ char *xmrig::Platform::createUserAgent() } +bool xmrig::Platform::hasKeepalive() +{ + return true; +} + + bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) { return true; diff --git a/src/base/kernel/Platform_unix.cpp b/src/base/kernel/Platform_unix.cpp index 4ffee214..43e8a742 100644 --- a/src/base/kernel/Platform_unix.cpp +++ b/src/base/kernel/Platform_unix.cpp @@ -70,6 +70,12 @@ char *xmrig::Platform::createUserAgent() } +bool xmrig::Platform::hasKeepalive() +{ + return true; +} + + #ifndef XMRIG_FEATURE_HWLOC #ifdef __DragonFly__ diff --git a/src/base/kernel/Platform_win.cpp b/src/base/kernel/Platform_win.cpp index 76d81ae5..ee04ee2a 100644 --- a/src/base/kernel/Platform_win.cpp +++ b/src/base/kernel/Platform_win.cpp @@ -70,6 +70,12 @@ char *xmrig::Platform::createUserAgent() } +bool xmrig::Platform::hasKeepalive() +{ + return winOsVersion().dwMajorVersion >= 6; +} + + #ifndef XMRIG_FEATURE_HWLOC bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) { diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index dfe2d664..06cc94fc 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -50,6 +50,7 @@ #include "base/tools/Cvt.h" #include "base/tools/cryptonote/BlobReader.h" #include "net/JobResult.h" +#include "base/kernel/Platform.h" #ifdef _MSC_VER @@ -567,9 +568,9 @@ void xmrig::Client::connect(const sockaddr *addr) uv_tcp_init(uv_default_loop(), m_socket); uv_tcp_nodelay(m_socket, 1); -# ifndef WIN32 - uv_tcp_keepalive(m_socket, 1, 60); -# endif + if (Platform::hasKeepalive()) { + uv_tcp_keepalive(m_socket, 1, 60); + } uv_tcp_connect(req, m_socket, addr, onConnect); } diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 9b1cdc42..b5e89d45 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -46,6 +46,7 @@ #include "base/tools/Timer.h" #include "base/tools/cryptonote/Signatures.h" #include "net/JobResult.h" +#include "base/kernel/Platform.h" #ifdef XMRIG_FEATURE_TLS @@ -358,9 +359,9 @@ void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, cons uv_tcp_init(uv_default_loop(), s); uv_tcp_nodelay(s, 1); -# ifndef WIN32 - uv_tcp_keepalive(s, 1, 60); -# endif + if (Platform::hasKeepalive()) { + uv_tcp_keepalive(s, 1, 60); + } if (m_pool.zmq_port() > 0) { delete m_ZMQSocket; From 12577df7bae70b8979c38e234d774cc900a8339e Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 6 Aug 2023 14:51:25 +0200 Subject: [PATCH 47/87] Disable TCP keepalive before closing socket --- src/base/net/stratum/Client.cpp | 3 +++ src/base/net/stratum/DaemonClient.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 06cc94fc..d780a5a8 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -344,6 +344,9 @@ bool xmrig::Client::close() setState(ClosingState); if (uv_is_closing(reinterpret_cast(m_socket)) == 0) { + if (Platform::hasKeepalive()) { + uv_tcp_keepalive(m_socket, 0, 60); + } uv_close(reinterpret_cast(m_socket), Client::onClose); } diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index b5e89d45..57d16685 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -590,6 +590,9 @@ void xmrig::DaemonClient::retry() } if ((m_ZMQConnectionState != ZMQ_NOT_CONNECTED) && (m_ZMQConnectionState != ZMQ_DISCONNECTING)) { + if (Platform::hasKeepalive()) { + uv_tcp_keepalive(m_ZMQSocket, 0, 60); + } uv_close(reinterpret_cast(m_ZMQSocket), onZMQClose); } @@ -917,6 +920,9 @@ bool xmrig::DaemonClient::ZMQClose(bool shutdown) m_ZMQConnectionState = ZMQ_DISCONNECTING; if (uv_is_closing(reinterpret_cast(m_ZMQSocket)) == 0) { + if (Platform::hasKeepalive()) { + uv_tcp_keepalive(m_ZMQSocket, 0, 60); + } uv_close(reinterpret_cast(m_ZMQSocket), shutdown ? onZMQShutdown : onZMQClose); if (!shutdown) { retry(); From 2ecf10cdcb98eb3a47bbd515eaea8a9097f46d27 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 6 Aug 2023 20:26:07 +0700 Subject: [PATCH 48/87] Make Platform::hasKeepalive() constexpr where always supported and code cleanup. --- src/base/kernel/Platform.h | 8 ++++++-- src/base/kernel/Platform_mac.cpp | 6 ------ src/base/kernel/Platform_unix.cpp | 6 ------ src/base/kernel/Platform_win.cpp | 5 ++--- src/base/net/stratum/Client.cpp | 8 ++++---- src/base/net/stratum/DaemonClient.cpp | 23 +++++++++++------------ 6 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/base/kernel/Platform.h b/src/base/kernel/Platform.h index b63a65fb..9e713d03 100644 --- a/src/base/kernel/Platform.h +++ b/src/base/kernel/Platform.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,7 +49,11 @@ public: static inline bool isUserActive(uint64_t ms) { return idleTime() < ms; } static inline const String &userAgent() { return m_userAgent; } +# ifdef XMRIG_OS_WIN static bool hasKeepalive(); +# else + static constexpr bool hasKeepalive() { return true; } +# endif static bool isOnBatteryPower(); static uint64_t idleTime(); diff --git a/src/base/kernel/Platform_mac.cpp b/src/base/kernel/Platform_mac.cpp index 8420d128..d07e925d 100644 --- a/src/base/kernel/Platform_mac.cpp +++ b/src/base/kernel/Platform_mac.cpp @@ -55,12 +55,6 @@ char *xmrig::Platform::createUserAgent() } -bool xmrig::Platform::hasKeepalive() -{ - return true; -} - - bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id) { return true; diff --git a/src/base/kernel/Platform_unix.cpp b/src/base/kernel/Platform_unix.cpp index 43e8a742..4ffee214 100644 --- a/src/base/kernel/Platform_unix.cpp +++ b/src/base/kernel/Platform_unix.cpp @@ -70,12 +70,6 @@ char *xmrig::Platform::createUserAgent() } -bool xmrig::Platform::hasKeepalive() -{ - return true; -} - - #ifndef XMRIG_FEATURE_HWLOC #ifdef __DragonFly__ diff --git a/src/base/kernel/Platform_win.cpp b/src/base/kernel/Platform_win.cpp index ee04ee2a..94d1282e 100644 --- a/src/base/kernel/Platform_win.cpp +++ b/src/base/kernel/Platform_win.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #include #include #include diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index d780a5a8..4dffd217 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 jtgrassie - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,15 +42,15 @@ #include "base/io/json/JsonRequest.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IClientListener.h" +#include "base/kernel/Platform.h" #include "base/net/dns/Dns.h" #include "base/net/dns/DnsRecords.h" #include "base/net/stratum/Socks5.h" #include "base/net/tools/NetBuffer.h" #include "base/tools/Chrono.h" -#include "base/tools/Cvt.h" #include "base/tools/cryptonote/BlobReader.h" +#include "base/tools/Cvt.h" #include "net/JobResult.h" -#include "base/kernel/Platform.h" #ifdef _MSC_VER diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 57d16685..37f352bc 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -1,13 +1,13 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2019 Howard Chu - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2010 Jeff Garzik + * Copyright (c) 2012-2014 pooler + * Copyright (c) 2014 Lucas Jones + * Copyright (c) 2014-2016 Wolf9466 + * Copyright (c) 2016 Jay D Dee + * Copyright (c) 2017-2018 XMR-Stak , + * Copyright (c) 2019 Howard Chu + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +23,6 @@ * along with this program. If not, see . */ - #include @@ -34,6 +33,7 @@ #include "base/io/json/JsonRequest.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IClientListener.h" +#include "base/kernel/Platform.h" #include "base/net/dns/Dns.h" #include "base/net/dns/DnsRecords.h" #include "base/net/http/Fetch.h" @@ -42,11 +42,10 @@ #include "base/net/stratum/SubmitResult.h" #include "base/net/tools/NetBuffer.h" #include "base/tools/bswap_64.h" +#include "base/tools/cryptonote/Signatures.h" #include "base/tools/Cvt.h" #include "base/tools/Timer.h" -#include "base/tools/cryptonote/Signatures.h" #include "net/JobResult.h" -#include "base/kernel/Platform.h" #ifdef XMRIG_FEATURE_TLS From dfe70d9ea7599e2aa057bacc2fed3098fbacd799 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 8 Aug 2023 17:48:44 +0700 Subject: [PATCH 49/87] Fixed huge pages availability info on Linux. --- src/crypto/common/VirtualMemory_unix.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index 99b96131..003b92e4 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2020 tevador - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "crypto/common/VirtualMemory.h" #include "backend/cpu/Cpu.h" #include "crypto/common/portable/mm_malloc.h" @@ -25,6 +24,7 @@ #include #include +#include #include @@ -84,7 +84,9 @@ static inline int hugePagesFlag(size_t size) bool xmrig::VirtualMemory::isHugepagesAvailable() { -# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM) +# ifdef XMRIG_OS_LINUX + return std::ifstream("/proc/sys/vm/nr_hugepages").good() || std::ifstream("/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages").good(); +# elif defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM) return false; # else return true; From 6e294bd0462f42cd0d5eb4d76ea7d65417c9c299 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 21 Aug 2023 13:37:54 +0200 Subject: [PATCH 50/87] Add "built for OS/architecture/bits" to "ABOUT" To make it more clear what binary it is on some XMRig screenshot. --- src/base/kernel/config/BaseConfig.cpp | 2 +- src/version.h | 35 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp index 37982999..d102a6ab 100644 --- a/src/base/kernel/config/BaseConfig.cpp +++ b/src/base/kernel/config/BaseConfig.cpp @@ -142,7 +142,7 @@ void xmrig::BaseConfig::printVersions() snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION); # endif - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s") WHITE_BOLD(" (built for %s") WHITE_BOLD(" %s,") WHITE_BOLD(" %s)"), "ABOUT", APP_NAME, APP_VERSION, buf, APP_OS, APP_ARCH, APP_BITS); std::string libs; diff --git a/src/version.h b/src/version.h index 2fc9bf98..5bf1b2f5 100644 --- a/src/version.h +++ b/src/version.h @@ -52,4 +52,39 @@ # endif #endif +#ifdef XMRIG_OS_WIN +# define APP_OS "Windows" +#elif defined XMRIG_OS_IOS +# define APP_OS "iOS" +#elif defined XMRIG_OS_MACOS +# define APP_OS "macOS" +#elif defined XMRIG_OS_ANDROID +# define APP_OS "Android" +#elif defined XMRIG_OS_LINUX +# define APP_OS "Linux" +#elif defined XMRIG_OS_FREEBSD +# define APP_OS "FreeBSD" +#else +# define APP_OS "Unknown OS" +#endif + +#define STR(X) #X +#define STR2(X) STR(X) + +#ifdef XMRIG_ARM +# define APP_ARCH "ARMv" STR2(XMRIG_ARM) +#else +# if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64) +# define APP_ARCH "x86-64" +# else +# define APP_ARCH "x86" +# endif +#endif + +#ifdef XMRIG_64_BIT +# define APP_BITS "64 bit" +#else +# define APP_BITS "32 bit" +#endif + #endif // XMRIG_VERSION_H From 0a3313cb761c0abf0e7e30964dcb125995eda96e Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 29 Sep 2023 08:33:01 +0200 Subject: [PATCH 51/87] Added SNI option for TLS connections Disabled by default, add `"sni": true,` to pool config to enable it. --- src/base/net/stratum/Client.cpp | 2 +- src/base/net/stratum/Pool.cpp | 3 +++ src/base/net/stratum/Pool.h | 3 +++ src/base/net/stratum/Tls.cpp | 6 +++++- src/base/net/stratum/Tls.h | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 4dffd217..50e35bcc 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -589,7 +589,7 @@ void xmrig::Client::handshake() if (isTLS()) { m_expire = Chrono::steadyMSecs() + kResponseTimeout; - m_tls->handshake(); + m_tls->handshake(m_pool.isSNI() ? m_pool.host().data() : nullptr); } else # endif diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index b1773c46..8b4a6e03 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -77,6 +77,7 @@ const char *Pool::kSelfSelect = "self-select"; const char *Pool::kSOCKS5 = "socks5"; const char *Pool::kSubmitToOrigin = "submit-to-origin"; const char *Pool::kTls = "tls"; +const char *Pool::kSni = "sni"; const char *Pool::kUrl = "url"; const char *Pool::kUser = "user"; const char *Pool::kSpendSecretKey = "spend-secret-key"; @@ -137,6 +138,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash) || m_url.host().contains(kNicehashHost)); m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS()); + m_flags.set(FLAG_SNI, Json::getBool(object, kSni)); setKeepAlive(Json::getValue(object, kKeepalive)); @@ -299,6 +301,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); obj.AddMember(StringRef(kTls), isTLS(), allocator); + obj.AddMember(StringRef(kSni), isSNI(), allocator); obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator); obj.AddMember(StringRef(kSOCKS5), m_proxy.toJSON(doc), allocator); diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 8374f20f..a8beee62 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -70,6 +70,7 @@ public: static const char *kSOCKS5; static const char *kSubmitToOrigin; static const char *kTls; + static const char* kSni; static const char *kUrl; static const char *kUser; static const char* kSpendSecretKey; @@ -95,6 +96,7 @@ public: inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); } inline bool isTLS() const { return m_flags.test(FLAG_TLS) || m_url.isTLS(); } + inline bool isSNI() const { return m_flags.test(FLAG_SNI); } inline bool isValid() const { return m_url.isValid(); } inline const Algorithm &algorithm() const { return m_algorithm; } inline const Coin &coin() const { return m_coin; } @@ -138,6 +140,7 @@ private: FLAG_ENABLED, FLAG_NICEHASH, FLAG_TLS, + FLAG_SNI, FLAG_MAX }; diff --git a/src/base/net/stratum/Tls.cpp b/src/base/net/stratum/Tls.cpp index 46ba4511..2a1ad1ee 100644 --- a/src/base/net/stratum/Tls.cpp +++ b/src/base/net/stratum/Tls.cpp @@ -60,7 +60,7 @@ xmrig::Client::Tls::~Tls() } -bool xmrig::Client::Tls::handshake() +bool xmrig::Client::Tls::handshake(const char* servername) { m_ssl = SSL_new(m_ctx); assert(m_ssl != nullptr); @@ -69,6 +69,10 @@ bool xmrig::Client::Tls::handshake() return false; } + if (servername) { + SSL_set_tlsext_host_name(m_ssl, servername); + } + SSL_set_connect_state(m_ssl); SSL_set_bio(m_ssl, m_read, m_write); SSL_do_handshake(m_ssl); diff --git a/src/base/net/stratum/Tls.h b/src/base/net/stratum/Tls.h index cfdda934..d399b439 100644 --- a/src/base/net/stratum/Tls.h +++ b/src/base/net/stratum/Tls.h @@ -42,7 +42,7 @@ public: Tls(Client *client); ~Tls(); - bool handshake(); + bool handshake(const char* servername); bool send(const char *data, size_t size); const char *fingerprint() const; const char *version() const; From f3446c0a9467ca9ed19eafa0952f3a2eb6e7f877 Mon Sep 17 00:00:00 2001 From: Jackson Zheng <60581068+JacksonZ03@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:12:58 +0100 Subject: [PATCH 52/87] Update cn_main_loop.asm I was scanning the code and found this line to be missing. Not sure if this was a mistake or if it was intentionally left out? --- src/crypto/cn/asm/cn_main_loop.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crypto/cn/asm/cn_main_loop.asm b/src/crypto/cn/asm/cn_main_loop.asm index 0979580a..da1c19a1 100644 --- a/src/crypto/cn/asm/cn_main_loop.asm +++ b/src/crypto/cn/asm/cn_main_loop.asm @@ -8,6 +8,7 @@ PUBLIC cnv2_mainloop_bulldozer_asm PUBLIC cnv2_double_mainloop_sandybridge_asm PUBLIC cnv2_rwz_mainloop_asm PUBLIC cnv2_rwz_double_mainloop_asm +PUBLIC cnv2_upx_double_mainloop_zen3_asm ALIGN(64) cnv1_single_mainloop_asm PROC From 2fa754825d86ca256f25e3774cd243f1a2112a0b Mon Sep 17 00:00:00 2001 From: Jackson Zheng <60581068+JacksonZ03@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:29:52 +0100 Subject: [PATCH 53/87] Update cn_main_loop.asm Found this line to be missing. I looked through the history and seemed like the original author of the commit missed it out. --- src/crypto/cn/asm/win64/cn_main_loop.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crypto/cn/asm/win64/cn_main_loop.asm b/src/crypto/cn/asm/win64/cn_main_loop.asm index 0979580a..da1c19a1 100644 --- a/src/crypto/cn/asm/win64/cn_main_loop.asm +++ b/src/crypto/cn/asm/win64/cn_main_loop.asm @@ -8,6 +8,7 @@ PUBLIC cnv2_mainloop_bulldozer_asm PUBLIC cnv2_double_mainloop_sandybridge_asm PUBLIC cnv2_rwz_mainloop_asm PUBLIC cnv2_rwz_double_mainloop_asm +PUBLIC cnv2_upx_double_mainloop_zen3_asm ALIGN(64) cnv1_single_mainloop_asm PROC From 5e66efabcf12e9b89265cd81d0526380ffe3111e Mon Sep 17 00:00:00 2001 From: SChernykh Date: Thu, 19 Oct 2023 17:39:25 +0200 Subject: [PATCH 54/87] ARM64 JIT: don't use `x18` register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms > The platforms reserve register x18. Don’t use this register. This PR fixes invalid hashes when running on Apple silicon with the latest macOS SDK. --- src/crypto/randomx/jit_compiler_a64.cpp | 54 +++++------ src/crypto/randomx/jit_compiler_a64_static.S | 98 ++++++++++---------- 2 files changed, 75 insertions(+), 77 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 530658db..05dac9f7 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -131,8 +131,8 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con // and w16, w10, ScratchpadL3Mask64 emit32(0x121A0000 | 16 | (10 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); - // and w17, w18, ScratchpadL3Mask64 - emit32(0x121A0000 | 17 | (18 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); + // and w17, w20, ScratchpadL3Mask64 + emit32(0x121A0000 | 17 | (20 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); codePos = PrologueSize; literalPos = ImulRcpLiteralsEnd; @@ -148,16 +148,16 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con } // Update spMix2 - // eor w18, config.readReg2, config.readReg3 - emit32(ARMV8A::EOR32 | 18 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos); + // eor w20, config.readReg2, config.readReg3 + emit32(ARMV8A::EOR32 | 20 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos); // Jump back to the main loop const uint32_t offset = (((uint8_t*)randomx_program_aarch64_vm_instructions_end) - ((uint8_t*)randomx_program_aarch64)) - codePos; emit32(ARMV8A::B | (offset / 4), code, codePos); - // and w18, w18, CacheLineAlignMask + // and w20, w20, CacheLineAlignMask codePos = (((uint8_t*)randomx_program_aarch64_cacheline_align_mask1) - ((uint8_t*)randomx_program_aarch64)); - emit32(0x121A0000 | 18 | (18 << 5) | ((RandomX_CurrentConfig.Log2_DatasetBaseSize - 7) << 10), code, codePos); + emit32(0x121A0000 | 20 | (20 << 5) | ((RandomX_CurrentConfig.Log2_DatasetBaseSize - 7) << 10), code, codePos); // and w10, w10, CacheLineAlignMask codePos = (((uint8_t*)randomx_program_aarch64_cacheline_align_mask2) - ((uint8_t*)randomx_program_aarch64)); @@ -189,8 +189,8 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration // and w16, w10, ScratchpadL3Mask64 emit32(0x121A0000 | 16 | (10 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); - // and w17, w18, ScratchpadL3Mask64 - emit32(0x121A0000 | 17 | (18 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); + // and w17, w20, ScratchpadL3Mask64 + emit32(0x121A0000 | 17 | (20 << 5) | ((RandomX_CurrentConfig.Log2_ScratchpadL3 - 7) << 10), code, codePos); codePos = PrologueSize; literalPos = ImulRcpLiteralsEnd; @@ -206,8 +206,8 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration } // Update spMix2 - // eor w18, config.readReg2, config.readReg3 - emit32(ARMV8A::EOR32 | 18 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos); + // eor w20, config.readReg2, config.readReg3 + emit32(ARMV8A::EOR32 | 20 | (IntRegMap[config.readReg2] << 5) | (IntRegMap[config.readReg3] << 16), code, codePos); // Jump back to the main loop const uint32_t offset = (((uint8_t*)randomx_program_aarch64_vm_instructions_end_light) - ((uint8_t*)randomx_program_aarch64)) - codePos; @@ -477,7 +477,7 @@ void JitCompilerA64::emitAddImmediate(uint32_t dst, uint32_t src, uint32_t imm, } else { - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMovImmediate(tmp_reg, imm, code, k); // add dst, src, tmp_reg @@ -526,7 +526,7 @@ void JitCompilerA64::emitMemLoadFP(uint32_t src, Instruction& instr, uint8_t* co uint32_t k = codePos; uint32_t imm = instr.getImm32(); - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 19; imm &= instr.getModMem() ? (RandomX_CurrentConfig.ScratchpadL1_Size - 1) : (RandomX_CurrentConfig.ScratchpadL2_Size - 1); emitAddImmediate(tmp_reg, src, imm, code, k); @@ -580,7 +580,7 @@ void JitCompilerA64::h_IADD_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // add dst, dst, tmp_reg @@ -618,7 +618,7 @@ void JitCompilerA64::h_ISUB_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // sub dst, dst, tmp_reg @@ -637,7 +637,7 @@ void JitCompilerA64::h_IMUL_R(Instruction& instr, uint32_t& codePos) if (src == dst) { - src = 18; + src = 20; emitMovImmediate(src, instr.getImm32(), code, k); } @@ -655,7 +655,7 @@ void JitCompilerA64::h_IMUL_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // sub dst, dst, tmp_reg @@ -686,7 +686,7 @@ void JitCompilerA64::h_IMULH_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // umulh dst, dst, tmp_reg @@ -717,7 +717,7 @@ void JitCompilerA64::h_ISMULH_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // smulh dst, dst, tmp_reg @@ -735,7 +735,7 @@ void JitCompilerA64::h_IMUL_RCP(Instruction& instr, uint32_t& codePos) uint32_t k = codePos; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; const uint32_t dst = IntRegMap[instr.dst]; constexpr uint64_t N = 1ULL << 63; @@ -754,9 +754,9 @@ void JitCompilerA64::h_IMUL_RCP(Instruction& instr, uint32_t& codePos) literalPos -= sizeof(uint64_t); *(uint64_t*)(code + literalPos) = (q << shift) + ((r << shift) / divisor); - if (literal_id < 13) + if (literal_id < 12) { - static constexpr uint32_t literal_regs[13] = { 30 << 16, 29 << 16, 28 << 16, 27 << 16, 26 << 16, 25 << 16, 24 << 16, 23 << 16, 22 << 16, 21 << 16, 20 << 16, 11 << 16, 0 }; + static constexpr uint32_t literal_regs[12] = { 30 << 16, 29 << 16, 28 << 16, 27 << 16, 26 << 16, 25 << 16, 24 << 16, 23 << 16, 22 << 16, 21 << 16, 11 << 16, 0 }; // mul dst, dst, literal_reg emit32(ARMV8A::MUL | dst | (dst << 5) | literal_regs[literal_id], code, k); @@ -794,7 +794,7 @@ void JitCompilerA64::h_IXOR_R(Instruction& instr, uint32_t& codePos) if (src == dst) { - src = 18; + src = 20; emitMovImmediate(src, instr.getImm32(), code, k); } @@ -812,7 +812,7 @@ void JitCompilerA64::h_IXOR_M(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emitMemLoad(dst, src, instr, code, k); // eor dst, dst, tmp_reg @@ -850,7 +850,7 @@ void JitCompilerA64::h_IROL_R(Instruction& instr, uint32_t& codePos) if (src != dst) { - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; // sub tmp_reg, xzr, src emit32(ARMV8A::SUB | tmp_reg | (31 << 5) | (src << 16), code, k); @@ -878,7 +878,7 @@ void JitCompilerA64::h_ISWAP_R(Instruction& instr, uint32_t& codePos) uint32_t k = codePos; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; emit32(ARMV8A::MOV_REG | tmp_reg | (dst << 16), code, k); emit32(ARMV8A::MOV_REG | dst | (src << 16), code, k); emit32(ARMV8A::MOV_REG | src | (tmp_reg << 16), code, k); @@ -1026,7 +1026,7 @@ void JitCompilerA64::h_CFROUND(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; constexpr uint32_t fpcr_tmp_reg = 8; // ror tmp_reg, src, imm @@ -1050,7 +1050,7 @@ void JitCompilerA64::h_ISTORE(Instruction& instr, uint32_t& codePos) const uint32_t src = IntRegMap[instr.src]; const uint32_t dst = IntRegMap[instr.dst]; - constexpr uint32_t tmp_reg = 18; + constexpr uint32_t tmp_reg = 20; uint32_t imm = instr.getImm32(); diff --git a/src/crypto/randomx/jit_compiler_a64_static.S b/src/crypto/randomx/jit_compiler_a64_static.S index 95a5c92c..e019c6b4 100644 --- a/src/crypto/randomx/jit_compiler_a64_static.S +++ b/src/crypto/randomx/jit_compiler_a64_static.S @@ -72,9 +72,9 @@ # x15 -> "r7" # x16 -> spAddr0 # x17 -> spAddr1 -# x18 -> temporary +# x18 -> unused (platform register, don't touch it) # x19 -> temporary -# x20 -> literal for IMUL_RCP +# x20 -> temporary # x21 -> literal for IMUL_RCP # x22 -> literal for IMUL_RCP # x23 -> literal for IMUL_RCP @@ -109,7 +109,7 @@ DECL(randomx_program_aarch64): # Save callee-saved registers sub sp, sp, 192 stp x16, x17, [sp] - stp x18, x19, [sp, 16] + str x19, [sp, 16] stp x20, x21, [sp, 32] stp x22, x23, [sp, 48] stp x24, x25, [sp, 64] @@ -164,7 +164,6 @@ DECL(randomx_program_aarch64): # Read literals ldr x0, literal_x0 ldr x11, literal_x11 - ldr x20, literal_x20 ldr x21, literal_x21 ldr x22, literal_x22 ldr x23, literal_x23 @@ -196,11 +195,11 @@ DECL(randomx_program_aarch64): DECL(randomx_program_aarch64_main_loop): # spAddr0 = spMix1 & ScratchpadL3Mask64; # spAddr1 = (spMix1 >> 32) & ScratchpadL3Mask64; - lsr x18, x10, 32 + lsr x20, x10, 32 # Actual mask will be inserted by JIT compiler and w16, w10, 1 - and w17, w18, 1 + and w17, w20, 1 # x16 = scratchpad + spAddr0 # x17 = scratchpad + spAddr1 @@ -208,31 +207,31 @@ DECL(randomx_program_aarch64_main_loop): add x17, x17, x2 # xor integer registers with scratchpad data (spAddr0) - ldp x18, x19, [x16] - eor x4, x4, x18 + ldp x20, x19, [x16] + eor x4, x4, x20 eor x5, x5, x19 - ldp x18, x19, [x16, 16] - eor x6, x6, x18 + ldp x20, x19, [x16, 16] + eor x6, x6, x20 eor x7, x7, x19 - ldp x18, x19, [x16, 32] - eor x12, x12, x18 + ldp x20, x19, [x16, 32] + eor x12, x12, x20 eor x13, x13, x19 - ldp x18, x19, [x16, 48] - eor x14, x14, x18 + ldp x20, x19, [x16, 48] + eor x14, x14, x20 eor x15, x15, x19 # Load group F registers (spAddr1) - ldpsw x18, x19, [x17] - ins v16.d[0], x18 + ldpsw x20, x19, [x17] + ins v16.d[0], x20 ins v16.d[1], x19 - ldpsw x18, x19, [x17, 8] - ins v17.d[0], x18 + ldpsw x20, x19, [x17, 8] + ins v17.d[0], x20 ins v17.d[1], x19 - ldpsw x18, x19, [x17, 16] - ins v18.d[0], x18 + ldpsw x20, x19, [x17, 16] + ins v18.d[0], x20 ins v18.d[1], x19 - ldpsw x18, x19, [x17, 24] - ins v19.d[0], x18 + ldpsw x20, x19, [x17, 24] + ins v19.d[0], x20 ins v19.d[1], x19 scvtf v16.2d, v16.2d scvtf v17.2d, v17.2d @@ -240,17 +239,17 @@ DECL(randomx_program_aarch64_main_loop): scvtf v19.2d, v19.2d # Load group E registers (spAddr1) - ldpsw x18, x19, [x17, 32] - ins v20.d[0], x18 + ldpsw x20, x19, [x17, 32] + ins v20.d[0], x20 ins v20.d[1], x19 - ldpsw x18, x19, [x17, 40] - ins v21.d[0], x18 + ldpsw x20, x19, [x17, 40] + ins v21.d[0], x20 ins v21.d[1], x19 - ldpsw x18, x19, [x17, 48] - ins v22.d[0], x18 + ldpsw x20, x19, [x17, 48] + ins v22.d[0], x20 ins v22.d[1], x19 - ldpsw x18, x19, [x17, 56] - ins v23.d[0], x18 + ldpsw x20, x19, [x17, 56] + ins v23.d[0], x20 ins v23.d[1], x19 scvtf v20.2d, v20.2d scvtf v21.2d, v21.2d @@ -273,7 +272,6 @@ DECL(randomx_program_aarch64_vm_instructions): literal_x0: .fill 1,8,0 literal_x11: .fill 1,8,0 -literal_x20: .fill 1,8,0 literal_x21: .fill 1,8,0 literal_x22: .fill 1,8,0 literal_x23: .fill 1,8,0 @@ -309,17 +307,17 @@ DECL(randomx_program_aarch64_vm_instructions_end): lsr x10, x9, 32 # mx ^= r[readReg2] ^ r[readReg3]; - eor x9, x9, x18 + eor x9, x9, x20 # Calculate dataset pointer for dataset prefetch - mov w18, w9 + mov w20, w9 DECL(randomx_program_aarch64_cacheline_align_mask1): # Actual mask will be inserted by JIT compiler - and x18, x18, 1 - add x18, x18, x1 + and x20, x20, 1 + add x20, x20, x1 # Prefetch dataset data - prfm pldl2strm, [x18] + prfm pldl2strm, [x20] # mx <-> ma ror x9, x9, 32 @@ -331,17 +329,17 @@ DECL(randomx_program_aarch64_cacheline_align_mask2): DECL(randomx_program_aarch64_xor_with_dataset_line): # xor integer registers with dataset data - ldp x18, x19, [x10] - eor x4, x4, x18 + ldp x20, x19, [x10] + eor x4, x4, x20 eor x5, x5, x19 - ldp x18, x19, [x10, 16] - eor x6, x6, x18 + ldp x20, x19, [x10, 16] + eor x6, x6, x20 eor x7, x7, x19 - ldp x18, x19, [x10, 32] - eor x12, x12, x18 + ldp x20, x19, [x10, 32] + eor x12, x12, x20 eor x13, x13, x19 - ldp x18, x19, [x10, 48] - eor x14, x14, x18 + ldp x20, x19, [x10, 48] + eor x14, x14, x20 eor x15, x15, x19 DECL(randomx_program_aarch64_update_spMix1): @@ -384,7 +382,7 @@ DECL(randomx_program_aarch64_update_spMix1): # Restore callee-saved registers ldp x16, x17, [sp] - ldp x18, x19, [sp, 16] + ldr x19, [sp, 16] ldp x20, x21, [sp, 32] ldp x22, x23, [sp, 48] ldp x24, x25, [sp, 64] @@ -405,7 +403,7 @@ DECL(randomx_program_aarch64_vm_instructions_end_light): stp x2, x30, [sp, 80] # mx ^= r[readReg2] ^ r[readReg3]; - eor x9, x9, x18 + eor x9, x9, x20 # mx <-> ma ror x9, x9, 32 @@ -447,8 +445,8 @@ DECL(randomx_program_aarch64_light_dataset_offset): # x3 -> end item DECL(randomx_init_dataset_aarch64): - # Save x30 (return address) - str x30, [sp, -16]! + # Save x20 (used as temporary, but must be saved to not break ABI) and x30 (return address) + stp x20, x30, [sp, -16]! # Load pointer to cache memory ldr x0, [x0] @@ -460,8 +458,8 @@ DECL(randomx_init_dataset_aarch64_main_loop): cmp x2, x3 bne DECL(randomx_init_dataset_aarch64_main_loop) - # Restore x30 (return address) - ldr x30, [sp], 16 + # Restore x20 and x30 + ldp x20, x30, [sp], 16 ret From 4131aa4754f23500e36ffa87a2eeb18433ecc7dd Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 30 Oct 2023 20:07:03 +0100 Subject: [PATCH 55/87] Update sse2neon.h --- src/crypto/cn/sse2neon.h | 1385 +++++++++++++++++++++----------------- 1 file changed, 765 insertions(+), 620 deletions(-) diff --git a/src/crypto/cn/sse2neon.h b/src/crypto/cn/sse2neon.h index 705e01cd..8d605973 100644 --- a/src/crypto/cn/sse2neon.h +++ b/src/crypto/cn/sse2neon.h @@ -26,6 +26,7 @@ // Jonathan Hue // Cuda Chen // Aymen Qader +// Anthony Roberts /* * sse2neon is freely redistributable under the MIT License. @@ -72,6 +73,13 @@ #define SSE2NEON_PRECISE_DP (0) #endif +/* Enable inclusion of windows.h on MSVC platforms + * This makes _mm_clflush functional on windows, as there is no builtin. + */ +#ifndef SSE2NEON_INCLUDE_WINDOWS_H +#define SSE2NEON_INCLUDE_WINDOWS_H (0) +#endif + /* compiler specific definitions */ #if defined(__GNUC__) || defined(__clang__) #pragma push_macro("FORCE_INLINE") @@ -80,8 +88,10 @@ #define ALIGN_STRUCT(x) __attribute__((aligned(x))) #define _sse2neon_likely(x) __builtin_expect(!!(x), 1) #define _sse2neon_unlikely(x) __builtin_expect(!!(x), 0) -#else /* non-GNU / non-clang compilers */ -#warning "Macro name collisions may happen with unsupported compiler." +#elif defined(_MSC_VER) +#if _MSVC_TRADITIONAL +#error Using the traditional MSVC preprocessor is not supported! Use /Zc:preprocessor instead. +#endif #ifndef FORCE_INLINE #define FORCE_INLINE static inline #endif @@ -90,6 +100,8 @@ #endif #define _sse2neon_likely(x) (x) #define _sse2neon_unlikely(x) (x) +#else +#pragma message("Macro name collisions may happen with unsupported compilers.") #endif /* C language does not allow initializing a variable with a function call. */ @@ -112,18 +124,65 @@ /* If using MSVC */ #ifdef _MSC_VER #include +#if SSE2NEON_INCLUDE_WINDOWS_H +#include +#include +#endif + +#if !defined(__cplusplus) +#error sse2neon only supports C++ compilation with this compiler +#endif + +#ifdef SSE2NEON_ALLOC_DEFINED +#include +#endif + #if (defined(_M_AMD64) || defined(__x86_64__)) || \ - (defined(_M_ARM) || defined(__arm__)) + (defined(_M_ARM64) || defined(__arm64__)) #define SSE2NEON_HAS_BITSCAN64 #endif #endif +#if defined(__GNUC__) || defined(__clang__) +#define _sse2neon_define0(type, s, body) \ + __extension__({ \ + type _a = (s); \ + body \ + }) +#define _sse2neon_define1(type, s, body) \ + __extension__({ \ + type _a = (s); \ + body \ + }) +#define _sse2neon_define2(type, a, b, body) \ + __extension__({ \ + type _a = (a), _b = (b); \ + body \ + }) +#define _sse2neon_return(ret) (ret) +#else +#define _sse2neon_define0(type, a, body) [=](type _a) { body }(a) +#define _sse2neon_define1(type, a, body) [](type _a) { body }(a) +#define _sse2neon_define2(type, a, b, body) \ + [](type _a, type _b) { body }((a), (b)) +#define _sse2neon_return(ret) return ret +#endif + +#define _sse2neon_init(...) \ + { \ + __VA_ARGS__ \ + } + /* Compiler barrier */ +#if defined(_MSC_VER) +#define SSE2NEON_BARRIER() _ReadWriteBarrier() +#else #define SSE2NEON_BARRIER() \ do { \ __asm__ __volatile__("" ::: "memory"); \ (void) 0; \ } while (0) +#endif /* Memory barriers * __atomic_thread_fence does not include a compiler barrier; instead, @@ -142,8 +201,8 @@ FORCE_INLINE void _sse2neon_smp_mb(void) atomic_thread_fence(memory_order_seq_cst); #elif defined(__GNUC__) || defined(__clang__) __atomic_thread_fence(__ATOMIC_SEQ_CST); -#else - /* FIXME: MSVC support */ +#else /* MSVC */ + __dmb(_ARM64_BARRIER_ISH); #endif } @@ -162,8 +221,8 @@ FORCE_INLINE void _sse2neon_smp_mb(void) #pragma GCC push_options #pragma GCC target("fpu=neon") #endif -#elif defined(__aarch64__) -#if !defined(__clang__) +#elif defined(__aarch64__) || defined(_M_ARM64) +#if !defined(__clang__) && !defined(_MSC_VER) #pragma GCC push_options #pragma GCC target("+simd") #endif @@ -172,7 +231,7 @@ FORCE_INLINE void _sse2neon_smp_mb(void) #error \ "You must enable NEON instructions (e.g. -mfpu=neon-fp-armv8) to use SSE2NEON." #endif -#if !defined(__clang__) +#if !defined(__clang__) && !defined(_MSC_VER) #pragma GCC push_options #endif #else @@ -181,14 +240,14 @@ FORCE_INLINE void _sse2neon_smp_mb(void) #endif #include -#if !defined(__aarch64__) && (__ARM_ARCH == 8) +#if (!defined(__aarch64__) && !defined(_M_ARM64)) && (__ARM_ARCH == 8) #if defined __has_include && __has_include() #include #endif #endif /* Apple Silicon cache lines are double of what is commonly used by Intel, AMD - * and other Arm microarchtectures use. + * and other Arm microarchitectures use. * From sysctl -a on Apple M1: * hw.cachelinesize: 128 */ @@ -198,8 +257,8 @@ FORCE_INLINE void _sse2neon_smp_mb(void) #define SSE2NEON_CACHELINE_SIZE 64 #endif -/* Rounding functions require either Aarch64 instructions or libm failback */ -#if !defined(__aarch64__) +/* Rounding functions require either Aarch64 instructions or libm fallback */ +#if !defined(__aarch64__) && !defined(_M_ARM64) #include #endif @@ -208,7 +267,7 @@ FORCE_INLINE void _sse2neon_smp_mb(void) * To write or access to these registers in user mode, * we have to perform syscall instead. */ -#if !defined(__aarch64__) +#if (!defined(__aarch64__) && !defined(_M_ARM64)) #include #endif @@ -308,7 +367,7 @@ typedef float32x4_t __m128; /* 128-bit vector containing 4 floats */ // On ARM 32-bit architecture, the float64x2_t is not supported. // The data type __m128d should be represented in a different way for related // intrinsic conversion. -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) typedef float64x2_t __m128d; /* 128-bit vector containing 2 doubles */ #else typedef float32x4_t __m128d; @@ -404,7 +463,7 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */ #define vreinterpret_f32_m64(x) vreinterpret_f32_s64(x) -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) #define vreinterpretq_m128d_s32(x) vreinterpretq_f64_s32(x) #define vreinterpretq_m128d_s64(x) vreinterpretq_f64_s64(x) @@ -485,7 +544,7 @@ typedef union ALIGN_STRUCT(16) SIMDVec { // Function declaration // SSE -FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE(); +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE(void); FORCE_INLINE __m128 _mm_move_ss(__m128, __m128); FORCE_INLINE __m128 _mm_or_ps(__m128, __m128); FORCE_INLINE __m128 _mm_set_ps1(float); @@ -501,7 +560,7 @@ FORCE_INLINE __m128i _mm_set_epi32(int, int, int, int); FORCE_INLINE __m128i _mm_set_epi64x(int64_t, int64_t); FORCE_INLINE __m128d _mm_set_pd(double, double); FORCE_INLINE __m128i _mm_set1_epi32(int); -FORCE_INLINE __m128i _mm_setzero_si128(); +FORCE_INLINE __m128i _mm_setzero_si128(void); // SSE4.1 FORCE_INLINE __m128d _mm_ceil_pd(__m128d); FORCE_INLINE __m128 _mm_ceil_ps(__m128); @@ -516,7 +575,7 @@ FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t, uint8_t); // Older gcc does not define vld1q_u8_x4 type #if defined(__GNUC__) && !defined(__clang__) && \ - ((__GNUC__ <= 12 && defined(__arm__)) || \ + ((__GNUC__ <= 13 && defined(__arm__)) || \ (__GNUC__ == 10 && __GNUC_MINOR__ < 3 && defined(__aarch64__)) || \ (__GNUC__ <= 9 && defined(__aarch64__))) FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) @@ -536,7 +595,7 @@ FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) } #endif -#if !defined(__aarch64__) +#if !defined(__aarch64__) && !defined(_M_ARM64) /* emulate vaddv u8 variant */ FORCE_INLINE uint8_t _sse2neon_vaddv_u8(uint8x8_t v8) { @@ -551,7 +610,7 @@ FORCE_INLINE uint8_t _sse2neon_vaddv_u8(uint8x8_t v8) } #endif -#if !defined(__aarch64__) +#if !defined(__aarch64__) && !defined(_M_ARM64) /* emulate vaddvq u8 variant */ FORCE_INLINE uint8_t _sse2neon_vaddvq_u8(uint8x16_t a) { @@ -569,7 +628,7 @@ FORCE_INLINE uint8_t _sse2neon_vaddvq_u8(uint8x16_t a) } #endif -#if !defined(__aarch64__) +#if !defined(__aarch64__) && !defined(_M_ARM64) /* emulate vaddvq u16 variant */ FORCE_INLINE uint16_t _sse2neon_vaddvq_u16(uint16x8_t a) { @@ -599,7 +658,7 @@ FORCE_INLINE uint16_t _sse2neon_vaddvq_u16(uint16x8_t a) * This last part, , is a little complicated. It identifies the * content of the input values, and can be set to any of the following values: * + ps - vectors contain floats (ps stands for packed single-precision) - * + pd - vectors cantain doubles (pd stands for packed double-precision) + * + pd - vectors contain doubles (pd stands for packed double-precision) * + epi8/epi16/epi32/epi64 - vectors contain 8-bit/16-bit/32-bit/64-bit * signed integers * + epu8/epu16/epu32/epu64 - vectors contain 8-bit/16-bit/32-bit/64-bit @@ -639,7 +698,7 @@ typedef struct { uint8_t bit23 : 1; uint8_t bit24 : 1; uint8_t res2 : 7; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint32_t res3; #endif } fpcr_bitfield; @@ -779,24 +838,24 @@ FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); } -// Kahan summation for accurate summation of floating-point numbers. -// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html -FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) -{ - y -= *c; - float t = *sum + y; - *c = (t - *sum) - y; - *sum = t; -} - -#if defined(__ARM_FEATURE_CRYPTO) && \ - (defined(__aarch64__) || __has_builtin(__builtin_arm_crypto_vmullp64)) +// For MSVC, we check only if it is ARM64, as every single ARM64 processor +// supported by WoA has crypto extensions. If this changes in the future, +// this can be verified via the runtime-only method of: +// IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) +#if (defined(_M_ARM64) && !defined(__clang__)) || \ + (defined(__ARM_FEATURE_CRYPTO) && \ + (defined(__aarch64__) || __has_builtin(__builtin_arm_crypto_vmullp64))) // Wraps vmull_p64 FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) { poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); +#if defined(_MSC_VER) + __n64 a1 = {a}, b1 = {b}; + return vreinterpretq_u64_p128(vmull_p64(a1, b1)); +#else return vreinterpretq_u64_p128(vmull_p64(a, b)); +#endif } #else // ARMv7 polyfill // ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. @@ -914,21 +973,17 @@ static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) // return ret; // } #define _mm_shuffle_epi32_default(a, imm) \ - __extension__({ \ - int32x4_t ret; \ - ret = vmovq_n_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ - ret, 1); \ - ret = vsetq_lane_s32( \ + vreinterpretq_m128i_s32(vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + vsetq_lane_s32( \ vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ - ret, 2); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ - ret, 3); \ - vreinterpretq_m128i_s32(ret); \ - }) + vsetq_lane_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), \ + ((imm) >> 2) & 0x3), \ + vmovq_n_s32(vgetq_lane_s32( \ + vreinterpretq_s32_m128i(a), (imm) & (0x3))), \ + 1), \ + 2), \ + 3)) // Takes the upper 64 bits of a and places it in the low end of the result // Takes the lower 64 bits of a and places it into the high end of the result. @@ -1012,20 +1067,13 @@ FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); } -// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) -// int imm) -#if defined(__aarch64__) -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ - }) +#if defined(__aarch64__) || defined(_M_ARM64) +#define _mm_shuffle_epi32_splat(a, imm) \ + vreinterpretq_m128i_s32(vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))) #else -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ - }) +#define _mm_shuffle_epi32_splat(a, imm) \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))) #endif // NEON does not support a general purpose permute intrinsic. @@ -1042,30 +1090,26 @@ FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) // } // // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_ps -#define _mm_shuffle_ps_default(a, b, imm) \ - __extension__({ \ - float32x4_t ret; \ - ret = vmovq_n_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ - ret, 1); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ - ret, 2); \ - ret = vsetq_lane_f32( \ - vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ - ret, 3); \ - vreinterpretq_m128_f32(ret); \ - }) +#define _mm_shuffle_ps_default(a, b, imm) \ + vreinterpretq_m128_f32(vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ + vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ + vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ + vmovq_n_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))), \ + 1), \ + 2), \ + 3)) // Shuffle 16-bit integers in the low 64 bits of a using the control in imm8. // Store the results in the low 64 bits of dst, with the high 64 bits being -// copied from from a to dst. +// copied from a to dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shufflelo_epi16 #define _mm_shufflelo_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ + _sse2neon_define1( \ + __m128i, a, int16x8_t ret = vreinterpretq_s16_m128i(_a); \ int16x4_t lowBits = vget_low_s16(ret); \ ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ @@ -1074,16 +1118,15 @@ FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) 2); \ ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ 3); \ - vreinterpretq_m128i_s16(ret); \ - }) + _sse2neon_return(vreinterpretq_m128i_s16(ret));) // Shuffle 16-bit integers in the high 64 bits of a using the control in imm8. // Store the results in the high 64 bits of dst, with the low 64 bits being -// copied from from a to dst. +// copied from a to dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shufflehi_epi16 #define _mm_shufflehi_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ + _sse2neon_define1( \ + __m128i, a, int16x8_t ret = vreinterpretq_s16_m128i(_a); \ int16x4_t highBits = vget_high_s16(ret); \ ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ @@ -1092,8 +1135,7 @@ FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) 6); \ ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ 7); \ - vreinterpretq_m128i_s16(ret); \ - }) + _sse2neon_return(vreinterpretq_m128i_s16(ret));) /* MMX */ @@ -1465,7 +1507,8 @@ FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvt_ps2pi FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) return vreinterpret_m64_s32( vget_low_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))))); #else @@ -1489,7 +1532,8 @@ FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvt_ss2si FORCE_INLINE int _mm_cvt_ss2si(__m128 a) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) return vgetq_lane_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))), 0); #else @@ -1619,7 +1663,8 @@ FORCE_INLINE float _mm_cvtss_f32(__m128 a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtss_si64 FORCE_INLINE int64_t _mm_cvtss_si64(__m128 a) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) return (int64_t) vgetq_lane_f32(vrndiq_f32(vreinterpretq_f32_m128(a)), 0); #else float32_t data = vgetq_lane_f32( @@ -1665,19 +1710,20 @@ FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) // Divide packed single-precision (32-bit) floating-point elements in a by // packed elements in b, and store the results in dst. +// Due to ARMv7-A NEON's lack of a precise division intrinsic, we implement +// division by multiplying a by b's reciprocal before using the Newton-Raphson +// method to approximate the results. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_ps FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) { -#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#if SSE2NEON_PRECISE_DIV // Additional Netwon-Raphson iteration for accuracy recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#endif return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); #endif } @@ -1686,6 +1732,8 @@ FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) // lower single-precision (32-bit) floating-point element in b, store the result // in the lower element of dst, and copy the upper 3 packed elements from a to // the upper elements of dst. +// Warning: ARMv7-A does not produce the same result compared to Intel and not +// IEEE-compliant. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_ss FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) { @@ -1710,23 +1758,43 @@ FORCE_INLINE void _mm_free(void *addr) } #endif +FORCE_INLINE uint64_t _sse2neon_get_fpcr(void) +{ + uint64_t value; +#if defined(_MSC_VER) + value = _ReadStatusReg(ARM64_FPCR); +#else + __asm__ __volatile__("mrs %0, FPCR" : "=r"(value)); /* read */ +#endif + return value; +} + +FORCE_INLINE void _sse2neon_set_fpcr(uint64_t value) +{ +#if defined(_MSC_VER) + _WriteStatusReg(ARM64_FPCR, value); +#else + __asm__ __volatile__("msr FPCR, %0" ::"r"(value)); /* write */ +#endif +} + // Macro: Get the flush zero bits from the MXCSR control and status register. // The flush zero may contain any of the following flags: _MM_FLUSH_ZERO_ON or // _MM_FLUSH_ZERO_OFF // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_FLUSH_ZERO_MODE -FORCE_INLINE unsigned int _sse2neon_mm_get_flush_zero_mode() +FORCE_INLINE unsigned int _sse2neon_mm_get_flush_zero_mode(void) { union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif @@ -1738,19 +1806,19 @@ FORCE_INLINE unsigned int _sse2neon_mm_get_flush_zero_mode() // The rounding mode may contain any of the following flags: _MM_ROUND_NEAREST, // _MM_ROUND_DOWN, _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_MM_GET_ROUNDING_MODE -FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE() +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE(void) { union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif @@ -1765,11 +1833,8 @@ FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE() // Copy a to dst, and insert the 16-bit integer i into dst at the location // specified by imm8. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_pi16 -#define _mm_insert_pi16(a, b, imm) \ - __extension__({ \ - vreinterpret_m64_s16( \ - vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ - }) +#define _mm_insert_pi16(a, b, imm) \ + vreinterpret_m64_s16(vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))) // Load 128-bits (composed of 4 packed single-precision (32-bit) floating-point // elements) from memory into dst. mem_addr must be aligned on a 16-byte @@ -2043,10 +2108,10 @@ FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) FORCE_INLINE int _mm_movemask_pi8(__m64 a) { uint8x8_t input = vreinterpret_u8_m64(a); -#if defined(__aarch64__) - static const int8x8_t shift = {0, 1, 2, 3, 4, 5, 6, 7}; +#if defined(__aarch64__) || defined(_M_ARM64) + static const int8_t shift[8] = {0, 1, 2, 3, 4, 5, 6, 7}; uint8x8_t tmp = vshr_n_u8(input, 7); - return vaddv_u8(vshl_u8(tmp, shift)); + return vaddv_u8(vshl_u8(tmp, vld1_s8(shift))); #else // Refer the implementation of `_mm_movemask_epi8` uint16x4_t high_bits = vreinterpret_u16_u8(vshr_n_u8(input, 7)); @@ -2064,10 +2129,10 @@ FORCE_INLINE int _mm_movemask_pi8(__m64 a) FORCE_INLINE int _mm_movemask_ps(__m128 a) { uint32x4_t input = vreinterpretq_u32_m128(a); -#if defined(__aarch64__) - static const int32x4_t shift = {0, 1, 2, 3}; +#if defined(__aarch64__) || defined(_M_ARM64) + static const int32_t shift[4] = {0, 1, 2, 3}; uint32x4_t tmp = vshrq_n_u32(input, 31); - return vaddvq_u32(vshlq_u32(tmp, shift)); + return vaddvq_u32(vshlq_u32(tmp, vld1q_s32(shift))); #else // Uses the exact same method as _mm_movemask_epi8, see that for details. // Shift out everything but the sign bits with a 32-bit unsigned shift @@ -2170,10 +2235,27 @@ FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) #define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) // Fetch the line of data from memory that contains address p to a location in -// the cache heirarchy specified by the locality hint i. +// the cache hierarchy specified by the locality hint i. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_prefetch FORCE_INLINE void _mm_prefetch(char const *p, int i) { + (void) i; +#if defined(_MSC_VER) + switch (i) { + case _MM_HINT_NTA: + __prefetch2(p, 1); + break; + case _MM_HINT_T0: + __prefetch2(p, 0); + break; + case _MM_HINT_T1: + __prefetch2(p, 2); + break; + case _MM_HINT_T2: + __prefetch2(p, 4); + break; + } +#else switch (i) { case _MM_HINT_NTA: __builtin_prefetch(p, 0, 0); @@ -2188,6 +2270,7 @@ FORCE_INLINE void _mm_prefetch(char const *p, int i) __builtin_prefetch(p, 0, 1); break; } +#endif } // Compute the absolute differences of packed unsigned 8-bit integers in a and @@ -2210,10 +2293,6 @@ FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) { float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); -#if SSE2NEON_PRECISE_DIV - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); -#endif return vreinterpretq_m128_f32(recip); } @@ -2234,13 +2313,24 @@ FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) { float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); -#if SSE2NEON_PRECISE_SQRT - // Additional Netwon-Raphson iteration for accuracy + + // Generate masks for detecting whether input has any 0.0f/-0.0f + // (which becomes positive/negative infinity by IEEE-754 arithmetic rules). + const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); + const uint32x4_t neg_inf = vdupq_n_u32(0xFF800000); + const uint32x4_t has_pos_zero = + vceqq_u32(pos_inf, vreinterpretq_u32_f32(out)); + const uint32x4_t has_neg_zero = + vceqq_u32(neg_inf, vreinterpretq_u32_f32(out)); + out = vmulq_f32( out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); - out = vmulq_f32( - out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); -#endif + + // Set output vector element to infinity/negative-infinity if + // the corresponding input vector element is 0.0f/-0.0f. + out = vbslq_f32(has_pos_zero, (float32x4_t) pos_inf, out); + out = vbslq_f32(has_neg_zero, (float32x4_t) neg_inf, out); + return vreinterpretq_m128_f32(out); } @@ -2264,7 +2354,7 @@ FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) uint64x1_t t = vpaddl_u32(vpaddl_u16( vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))))); return vreinterpret_m64_u16( - vset_lane_u16(vget_lane_u64(t, 0), vdup_n_u16(0), 0)); + vset_lane_u16((int) vget_lane_u64(t, 0), vdup_n_u16(0), 0)); } // Macro: Set the flush zero bits of the MXCSR control and status register to @@ -2277,23 +2367,23 @@ FORCE_INLINE void _sse2neon_mm_set_flush_zero_mode(unsigned int flag) // regardless of the value of the FZ bit. union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif r.field.bit24 = (flag & _MM_FLUSH_ZERO_MASK) == _MM_FLUSH_ZERO_ON; -#if defined(__aarch64__) - __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#if defined(__aarch64__) || defined(_M_ARM64) + _sse2neon_set_fpcr(r.value); #else __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ #endif @@ -2325,15 +2415,15 @@ FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) { union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif @@ -2356,8 +2446,8 @@ FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) r.field.bit23 = 0; } -#if defined(__aarch64__) - __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#if defined(__aarch64__) || defined(_M_ARM64) + _sse2neon_set_fpcr(r.value); #else __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ #endif @@ -2391,7 +2481,7 @@ FORCE_INLINE void _mm_setcsr(unsigned int a) // Get the unsigned 32-bit value of the MXCSR control and status register. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_getcsr // FIXME: _mm_getcsr() implementation supports reading the rounding mode only. -FORCE_INLINE unsigned int _mm_getcsr() +FORCE_INLINE unsigned int _mm_getcsr(void) { return _MM_GET_ROUNDING_MODE(); } @@ -2416,29 +2506,26 @@ FORCE_INLINE __m128 _mm_setzero_ps(void) // in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_pi16 #ifdef _sse2neon_shuffle -#define _mm_shuffle_pi16(a, imm) \ - __extension__({ \ - vreinterpret_m64_s16(vshuffle_s16( \ - vreinterpret_s16_m64(a), vreinterpret_s16_m64(a), (imm & 0x3), \ - ((imm >> 2) & 0x3), ((imm >> 4) & 0x3), ((imm >> 6) & 0x3))); \ - }) +#define _mm_shuffle_pi16(a, imm) \ + vreinterpret_m64_s16(vshuffle_s16( \ + vreinterpret_s16_m64(a), vreinterpret_s16_m64(a), (imm & 0x3), \ + ((imm >> 2) & 0x3), ((imm >> 4) & 0x3), ((imm >> 6) & 0x3))) #else -#define _mm_shuffle_pi16(a, imm) \ - __extension__({ \ - int16x4_t ret; \ - ret = \ - vmov_n_s16(vget_lane_s16(vreinterpret_s16_m64(a), (imm) & (0x3))); \ - ret = vset_lane_s16( \ - vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 2) & 0x3), ret, \ - 1); \ - ret = vset_lane_s16( \ - vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 4) & 0x3), ret, \ - 2); \ - ret = vset_lane_s16( \ - vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 6) & 0x3), ret, \ - 3); \ - vreinterpret_m64_s16(ret); \ - }) +#define _mm_shuffle_pi16(a, imm) \ + _sse2neon_define1( \ + __m64, a, int16x4_t ret; \ + ret = vmov_n_s16( \ + vget_lane_s16(vreinterpret_s16_m64(_a), (imm) & (0x3))); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(_a), ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(_a), ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(_a), ((imm) >> 6) & 0x3), ret, \ + 3); \ + _sse2neon_return(vreinterpret_m64_s16(ret));) #endif // Perform a serializing operation on all store-to-memory instructions that were @@ -2485,75 +2572,77 @@ FORCE_INLINE void _mm_lfence(void) vreinterpretq_m128_f32(_shuf); \ }) #else // generic -#define _mm_shuffle_ps(a, b, imm) \ - __extension__({ \ - __m128 ret; \ - switch (imm) { \ - case _MM_SHUFFLE(1, 0, 3, 2): \ - ret = _mm_shuffle_ps_1032((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 3, 0, 1): \ - ret = _mm_shuffle_ps_2301((a), (b)); \ - break; \ - case _MM_SHUFFLE(0, 3, 2, 1): \ - ret = _mm_shuffle_ps_0321((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 1, 0, 3): \ - ret = _mm_shuffle_ps_2103((a), (b)); \ - break; \ - case _MM_SHUFFLE(1, 0, 1, 0): \ - ret = _mm_movelh_ps((a), (b)); \ - break; \ - case _MM_SHUFFLE(1, 0, 0, 1): \ - ret = _mm_shuffle_ps_1001((a), (b)); \ - break; \ - case _MM_SHUFFLE(0, 1, 0, 1): \ - ret = _mm_shuffle_ps_0101((a), (b)); \ - break; \ - case _MM_SHUFFLE(3, 2, 1, 0): \ - ret = _mm_shuffle_ps_3210((a), (b)); \ - break; \ - case _MM_SHUFFLE(0, 0, 1, 1): \ - ret = _mm_shuffle_ps_0011((a), (b)); \ - break; \ - case _MM_SHUFFLE(0, 0, 2, 2): \ - ret = _mm_shuffle_ps_0022((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 2, 0, 0): \ - ret = _mm_shuffle_ps_2200((a), (b)); \ - break; \ - case _MM_SHUFFLE(3, 2, 0, 2): \ - ret = _mm_shuffle_ps_3202((a), (b)); \ - break; \ - case _MM_SHUFFLE(3, 2, 3, 2): \ - ret = _mm_movehl_ps((b), (a)); \ - break; \ - case _MM_SHUFFLE(1, 1, 3, 3): \ - ret = _mm_shuffle_ps_1133((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 0, 1, 0): \ - ret = _mm_shuffle_ps_2010((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 0, 0, 1): \ - ret = _mm_shuffle_ps_2001((a), (b)); \ - break; \ - case _MM_SHUFFLE(2, 0, 3, 2): \ - ret = _mm_shuffle_ps_2032((a), (b)); \ - break; \ - default: \ - ret = _mm_shuffle_ps_default((a), (b), (imm)); \ - break; \ - } \ - ret; \ - }) +#define _mm_shuffle_ps(a, b, imm) \ + _sse2neon_define2( \ + __m128, a, b, __m128 ret; switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_ps_1032(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_ps_2301(_a, _b); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_ps_0321(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_ps_2103(_a, _b); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_movelh_ps(_a, _b); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_ps_1001(_a, _b); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_ps_0101(_a, _b); \ + break; \ + case _MM_SHUFFLE(3, 2, 1, 0): \ + ret = _mm_shuffle_ps_3210(_a, _b); \ + break; \ + case _MM_SHUFFLE(0, 0, 1, 1): \ + ret = _mm_shuffle_ps_0011(_a, _b); \ + break; \ + case _MM_SHUFFLE(0, 0, 2, 2): \ + ret = _mm_shuffle_ps_0022(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 2, 0, 0): \ + ret = _mm_shuffle_ps_2200(_a, _b); \ + break; \ + case _MM_SHUFFLE(3, 2, 0, 2): \ + ret = _mm_shuffle_ps_3202(_a, _b); \ + break; \ + case _MM_SHUFFLE(3, 2, 3, 2): \ + ret = _mm_movehl_ps(_b, _a); \ + break; \ + case _MM_SHUFFLE(1, 1, 3, 3): \ + ret = _mm_shuffle_ps_1133(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 0, 1, 0): \ + ret = _mm_shuffle_ps_2010(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 0, 0, 1): \ + ret = _mm_shuffle_ps_2001(_a, _b); \ + break; \ + case _MM_SHUFFLE(2, 0, 3, 2): \ + ret = _mm_shuffle_ps_2032(_a, _b); \ + break; \ + default: \ + ret = _mm_shuffle_ps_default(_a, _b, (imm)); \ + break; \ + } _sse2neon_return(ret);) #endif // Compute the square root of packed single-precision (32-bit) floating-point // elements in a, and store the results in dst. +// Due to ARMv7-A NEON's lack of a precise square root intrinsic, we implement +// square root by multiplying input in with its reciprocal square root before +// using the Newton-Raphson method to approximate the results. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_ps FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) { -#if SSE2NEON_PRECISE_SQRT +#if defined(__aarch64__) || defined(_M_ARM64) + return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); +#else float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); // Test for vrsqrteq_f32(0) -> positive infinity case. @@ -2564,22 +2653,16 @@ FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) recip = vreinterpretq_f32_u32( vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); - // Additional Netwon-Raphson iteration for accuracy recip = vmulq_f32( vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), recip); + // Additional Netwon-Raphson iteration for accuracy recip = vmulq_f32( vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), recip); // sqrt(s) = s * 1/sqrt(s) return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); -#elif defined(__aarch64__) - return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); -#else - float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); - float32x4_t sq = vrecpeq_f32(recipsq); - return vreinterpretq_m128_f32(sq); #endif } @@ -2754,6 +2837,9 @@ FORCE_INLINE __m128i _mm_undefined_si128(void) #pragma GCC diagnostic ignored "-Wuninitialized" #endif __m128i a; +#if defined(_MSC_VER) + a = _mm_setzero_si128(); +#endif return a; #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop @@ -2769,6 +2855,9 @@ FORCE_INLINE __m128 _mm_undefined_ps(void) #pragma GCC diagnostic ignored "-Wuninitialized" #endif __m128 a; +#if defined(_MSC_VER) + a = _mm_setzero_ps(); +#endif return a; #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop @@ -2780,7 +2869,7 @@ FORCE_INLINE __m128 _mm_undefined_ps(void) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_ps FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else @@ -2796,7 +2885,7 @@ FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_ps FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else @@ -2855,7 +2944,7 @@ FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_pd FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -2874,7 +2963,7 @@ FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_sd FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_add_pd(a, b)); #else double *da = (double *) &a; @@ -3033,7 +3122,7 @@ FORCE_INLINE __m128i _mm_castps_si128(__m128 a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castsi128_pd FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); #else return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); @@ -3068,8 +3157,8 @@ FORCE_INLINE void _mm_clflush(void const *p) uintptr_t ptr = (uintptr_t) p; __builtin___clear_cache((char *) ptr, (char *) ptr + SSE2NEON_CACHELINE_SIZE); -#else - /* FIXME: MSVC support */ +#elif (_MSC_VER) && SSE2NEON_INCLUDE_WINDOWS_H + FlushInstructionCache(GetCurrentProcess(), p, SSE2NEON_CACHELINE_SIZE); #endif } @@ -3105,7 +3194,7 @@ FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_pd FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64( vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -3131,7 +3220,7 @@ FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpge_pd FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64( vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -3153,7 +3242,7 @@ FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpge_sd FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmpge_pd(a, b)); #else // expand "_mm_cmpge_pd()" to reduce unnecessary operations @@ -3200,7 +3289,7 @@ FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_pd FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64( vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -3222,7 +3311,7 @@ FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_sd FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmpgt_pd(a, b)); #else // expand "_mm_cmpge_pd()" to reduce unnecessary operations @@ -3242,7 +3331,7 @@ FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmple_pd FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64( vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -3264,7 +3353,7 @@ FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmple_sd FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmple_pd(a, b)); #else // expand "_mm_cmpge_pd()" to reduce unnecessary operations @@ -3314,7 +3403,7 @@ FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_pd FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64( vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -3336,7 +3425,7 @@ FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_sd FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmplt_pd(a, b)); #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3355,7 +3444,7 @@ FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpneq_pd FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64( vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))))); #else @@ -3381,7 +3470,7 @@ FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnge_pd FORCE_INLINE __m128d _mm_cmpnge_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64(veorq_u64( vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), vdupq_n_u64(UINT64_MAX))); @@ -3414,7 +3503,7 @@ FORCE_INLINE __m128d _mm_cmpnge_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_cmpngt_pd FORCE_INLINE __m128d _mm_cmpngt_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64(veorq_u64( vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), vdupq_n_u64(UINT64_MAX))); @@ -3447,7 +3536,7 @@ FORCE_INLINE __m128d _mm_cmpngt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnle_pd FORCE_INLINE __m128d _mm_cmpnle_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64(veorq_u64( vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), vdupq_n_u64(UINT64_MAX))); @@ -3480,7 +3569,7 @@ FORCE_INLINE __m128d _mm_cmpnle_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnlt_pd FORCE_INLINE __m128d _mm_cmpnlt_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_u64(veorq_u64( vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), vdupq_n_u64(UINT64_MAX))); @@ -3513,7 +3602,7 @@ FORCE_INLINE __m128d _mm_cmpnlt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpord_pd FORCE_INLINE __m128d _mm_cmpord_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) // Excluding NaNs, any two floating point numbers can be compared. uint64x2_t not_nan_a = vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); @@ -3545,7 +3634,7 @@ FORCE_INLINE __m128d _mm_cmpord_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpord_sd FORCE_INLINE __m128d _mm_cmpord_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmpord_pd(a, b)); #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3567,7 +3656,7 @@ FORCE_INLINE __m128d _mm_cmpord_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpunord_pd FORCE_INLINE __m128d _mm_cmpunord_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) // Two NaNs are not equal in comparison operation. uint64x2_t not_nan_a = vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); @@ -3600,7 +3689,7 @@ FORCE_INLINE __m128d _mm_cmpunord_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpunord_sd FORCE_INLINE __m128d _mm_cmpunord_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_cmpunord_pd(a, b)); #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3622,7 +3711,7 @@ FORCE_INLINE __m128d _mm_cmpunord_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comige_sd FORCE_INLINE int _mm_comige_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_u64(vcgeq_f64(a, b), 0) & 0x1; #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3637,7 +3726,7 @@ FORCE_INLINE int _mm_comige_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comigt_sd FORCE_INLINE int _mm_comigt_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_u64(vcgtq_f64(a, b), 0) & 0x1; #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3652,7 +3741,7 @@ FORCE_INLINE int _mm_comigt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comile_sd FORCE_INLINE int _mm_comile_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_u64(vcleq_f64(a, b), 0) & 0x1; #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3667,7 +3756,7 @@ FORCE_INLINE int _mm_comile_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comilt_sd FORCE_INLINE int _mm_comilt_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_u64(vcltq_f64(a, b), 0) & 0x1; #else uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); @@ -3682,7 +3771,7 @@ FORCE_INLINE int _mm_comilt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comieq_sd FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_u64(vceqq_f64(a, b), 0) & 0x1; #else uint32x4_t a_not_nan = @@ -3711,7 +3800,7 @@ FORCE_INLINE int _mm_comineq_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtepi32_pd FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vcvtq_f64_s64(vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a))))); #else @@ -3766,7 +3855,7 @@ FORCE_INLINE __m64 _mm_cvtpd_pi32(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtpd_ps FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); #else @@ -3781,7 +3870,7 @@ FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtpi32_pd FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a)))); #else @@ -3800,7 +3889,8 @@ FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) { #if defined(__ARM_FEATURE_FRINT) return vreinterpretq_m128i_s32(vcvtq_s32_f32(vrnd32xq_f32(a))); -#elif defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#elif (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) switch (_MM_GET_ROUNDING_MODE()) { case _MM_ROUND_NEAREST: return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); @@ -3853,7 +3943,7 @@ FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_pd FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); #else @@ -3867,7 +3957,7 @@ FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_f64 FORCE_INLINE double _mm_cvtsd_f64(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); #else return ((double *) &a)[0]; @@ -3879,7 +3969,7 @@ FORCE_INLINE double _mm_cvtsd_f64(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_si32 FORCE_INLINE int32_t _mm_cvtsd_si32(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return (int32_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); #else __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); @@ -3893,7 +3983,7 @@ FORCE_INLINE int32_t _mm_cvtsd_si32(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_si64 FORCE_INLINE int64_t _mm_cvtsd_si64(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return (int64_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); #else __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); @@ -3914,7 +4004,7 @@ FORCE_INLINE int64_t _mm_cvtsd_si64(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_ss FORCE_INLINE __m128 _mm_cvtsd_ss(__m128 a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32(vsetq_lane_f32( vget_lane_f32(vcvt_f32_f64(vreinterpretq_f64_m128d(b)), 0), vreinterpretq_f32_m128(a), 0)); @@ -3948,7 +4038,7 @@ FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi32_sd FORCE_INLINE __m128d _mm_cvtsi32_sd(__m128d a, int32_t b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); #else @@ -3976,7 +4066,7 @@ FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi64_sd FORCE_INLINE __m128d _mm_cvtsi64_sd(__m128d a, int64_t b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); #else @@ -4013,7 +4103,7 @@ FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) { double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); #else @@ -4065,7 +4155,7 @@ FORCE_INLINE int32_t _mm_cvttsd_si32(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvttsd_si64 FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); #else double ret = *((double *) &a); @@ -4083,7 +4173,7 @@ FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_pd FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -4103,7 +4193,7 @@ FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_sd FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float64x2_t tmp = vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)); return vreinterpretq_m128d_f64( @@ -4125,11 +4215,9 @@ FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi16 // FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, // __constrange(0,8) int imm) -#define _mm_insert_epi16(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s16( \ - vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ - }) +#define _mm_insert_epi16(a, b, imm) \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))) // Load 128-bits (composed of 2 packed double-precision (64-bit) floating-point // elements) from memory into dst. mem_addr must be aligned on a 16-byte @@ -4137,7 +4225,7 @@ FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_pd FORCE_INLINE __m128d _mm_load_pd(const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vld1q_f64(p)); #else const float *fp = (const float *) p; @@ -4157,7 +4245,7 @@ FORCE_INLINE __m128d _mm_load_pd(const double *p) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_sd FORCE_INLINE __m128d _mm_load_sd(const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); #else const float *fp = (const float *) p; @@ -4179,7 +4267,7 @@ FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load1_pd FORCE_INLINE __m128d _mm_load1_pd(const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); #else return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); @@ -4192,7 +4280,7 @@ FORCE_INLINE __m128d _mm_load1_pd(const double *p) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadh_pd FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); #else @@ -4218,7 +4306,7 @@ FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadl_pd FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); #else @@ -4234,7 +4322,7 @@ FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadr_pd FORCE_INLINE __m128d _mm_loadr_pd(const double *p) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float64x2_t v = vld1q_f64(p); return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); #else @@ -4274,7 +4362,7 @@ FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) { int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), vget_low_s16(vreinterpretq_s16_m128i(b))); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int32x4_t high = vmull_high_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)); @@ -4328,7 +4416,7 @@ FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_pd FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) #if SSE2NEON_PRECISE_MINMAX float64x2_t _a = vreinterpretq_f64_m128d(a); float64x2_t _b = vreinterpretq_f64_m128d(b); @@ -4356,7 +4444,7 @@ FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_sd FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_max_pd(a, b)); #else double *da = (double *) &a; @@ -4389,7 +4477,7 @@ FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_pd FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) #if SSE2NEON_PRECISE_MINMAX float64x2_t _a = vreinterpretq_f64_m128d(a); float64x2_t _b = vreinterpretq_f64_m128d(b); @@ -4416,7 +4504,7 @@ FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_sd FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_min_pd(a, b)); #else double *da = (double *) &a; @@ -4536,7 +4624,8 @@ FORCE_INLINE int _mm_movemask_pd(__m128d a) { uint64x2_t input = vreinterpretq_u64_m128d(a); uint64x2_t high_bits = vshrq_n_u64(input, 63); - return vgetq_lane_u64(high_bits, 0) | (vgetq_lane_u64(high_bits, 1) << 1); + return (int) (vgetq_lane_u64(high_bits, 0) | + (vgetq_lane_u64(high_bits, 1) << 1)); } // Copy the lower 64-bit integer in a to dst. @@ -4571,7 +4660,7 @@ FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mul_pd FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -4632,7 +4721,7 @@ FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a)); uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b)); uint32x4_t ab3210 = vmull_u16(a3210, b3210); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint32x4_t ab7654 = vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)); uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210), @@ -4711,9 +4800,13 @@ FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) // Arm cores. Experience with several databases has shown has shown an 'isb' is // a reasonable approximation. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_pause -FORCE_INLINE void _mm_pause() +FORCE_INLINE void _mm_pause(void) { +#if defined(_MSC_VER) + __isb(_ARM64_BARRIER_SY); +#else __asm__ __volatile__("isb\n"); +#endif } // Compute the absolute differences of packed unsigned 8-bit integers in a and @@ -4754,7 +4847,7 @@ FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_epi64 FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) { - return _mm_set_epi64x((int64_t) i1, (int64_t) i2); + return _mm_set_epi64x(vget_lane_s64(i1, 0), vget_lane_s64(i2, 0)); } // Set packed 64-bit integers in dst with the supplied values. @@ -4798,7 +4891,7 @@ FORCE_INLINE __m128i _mm_set_epi8(signed char b15, FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) { double ALIGN_STRUCT(16) data[2] = {e0, e1}; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); #else return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); @@ -4815,14 +4908,14 @@ FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_sd FORCE_INLINE __m128d _mm_set_sd(double a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vsetq_lane_f64(a, vdupq_n_f64(0), 0)); #else return _mm_set_pd(0, a); #endif } -// Broadcast 16-bit integer a to all all elements of dst. +// Broadcast 16-bit integer a to all elements of dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi16 FORCE_INLINE __m128i _mm_set1_epi16(short w) { @@ -4840,7 +4933,7 @@ FORCE_INLINE __m128i _mm_set1_epi32(int _i) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi64 FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) { - return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); + return vreinterpretq_m128i_s64(vdupq_lane_s64(_i, 0)); } // Broadcast 64-bit integer a to all elements of dst. @@ -4862,7 +4955,7 @@ FORCE_INLINE __m128i _mm_set1_epi8(signed char w) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_pd FORCE_INLINE __m128d _mm_set1_pd(double d) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vdupq_n_f64(d)); #else return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); @@ -4938,7 +5031,7 @@ FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setzero_pd FORCE_INLINE __m128d _mm_setzero_pd(void) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vdupq_n_f64(0)); #else return vreinterpretq_m128d_f32(vdupq_n_f32(0)); @@ -4957,7 +5050,7 @@ FORCE_INLINE __m128i _mm_setzero_si128(void) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi32 // FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, // __constrange(0,255) int imm) -#ifdef _sse2neon_shuffle +#if defined(_sse2neon_shuffle) #define _mm_shuffle_epi32(a, imm) \ __extension__({ \ int32x4_t _input = vreinterpretq_s32_m128i(a); \ @@ -4967,58 +5060,55 @@ FORCE_INLINE __m128i _mm_setzero_si128(void) vreinterpretq_m128i_s32(_shuf); \ }) #else // generic -#define _mm_shuffle_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - switch (imm) { \ - case _MM_SHUFFLE(1, 0, 3, 2): \ - ret = _mm_shuffle_epi_1032((a)); \ - break; \ - case _MM_SHUFFLE(2, 3, 0, 1): \ - ret = _mm_shuffle_epi_2301((a)); \ - break; \ - case _MM_SHUFFLE(0, 3, 2, 1): \ - ret = _mm_shuffle_epi_0321((a)); \ - break; \ - case _MM_SHUFFLE(2, 1, 0, 3): \ - ret = _mm_shuffle_epi_2103((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 1, 0): \ - ret = _mm_shuffle_epi_1010((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 0, 1): \ - ret = _mm_shuffle_epi_1001((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 0, 1): \ - ret = _mm_shuffle_epi_0101((a)); \ - break; \ - case _MM_SHUFFLE(2, 2, 1, 1): \ - ret = _mm_shuffle_epi_2211((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 2, 2): \ - ret = _mm_shuffle_epi_0122((a)); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 2): \ - ret = _mm_shuffle_epi_3332((a)); \ - break; \ - case _MM_SHUFFLE(0, 0, 0, 0): \ - ret = _mm_shuffle_epi32_splat((a), 0); \ - break; \ - case _MM_SHUFFLE(1, 1, 1, 1): \ - ret = _mm_shuffle_epi32_splat((a), 1); \ - break; \ - case _MM_SHUFFLE(2, 2, 2, 2): \ - ret = _mm_shuffle_epi32_splat((a), 2); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 3): \ - ret = _mm_shuffle_epi32_splat((a), 3); \ - break; \ - default: \ - ret = _mm_shuffle_epi32_default((a), (imm)); \ - break; \ - } \ - ret; \ - }) +#define _mm_shuffle_epi32(a, imm) \ + _sse2neon_define1( \ + __m128i, a, __m128i ret; switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032(_a); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301(_a); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321(_a); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103(_a); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010(_a); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001(_a); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101(_a); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211(_a); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122(_a); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332(_a); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat(_a, 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat(_a, 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat(_a, 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat(_a, 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default(_a, (imm)); \ + break; \ + } _sse2neon_return(ret);) #endif // Shuffle double-precision (64-bit) floating-point elements using the control @@ -5038,7 +5128,7 @@ FORCE_INLINE __m128i _mm_setzero_si128(void) // FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, // __constrange(0,255) int imm) -#ifdef _sse2neon_shuffle +#if defined(_sse2neon_shuffle) #define _mm_shufflehi_epi16(a, imm) \ __extension__({ \ int16x8_t _input = vreinterpretq_s16_m128i(a); \ @@ -5054,7 +5144,7 @@ FORCE_INLINE __m128i _mm_setzero_si128(void) // FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, // __constrange(0,255) int imm) -#ifdef _sse2neon_shuffle +#if defined(_sse2neon_shuffle) #define _mm_shufflelo_epi16(a, imm) \ __extension__({ \ int16x8_t _input = vreinterpretq_s16_m128i(a); \ @@ -5142,25 +5232,21 @@ FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) // Shift a left by imm8 bytes while shifting in zeros, and store the results in // dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_slli_si128 -#define _mm_slli_si128(a, imm) \ - __extension__({ \ - int8x16_t ret; \ - if (_sse2neon_unlikely(imm == 0)) \ - ret = vreinterpretq_s8_m128i(a); \ - else if (_sse2neon_unlikely((imm) & ~15)) \ - ret = vdupq_n_s8(0); \ - else \ - ret = vextq_s8(vdupq_n_s8(0), vreinterpretq_s8_m128i(a), \ - ((imm <= 0 || imm > 15) ? 0 : (16 - imm))); \ - vreinterpretq_m128i_s8(ret); \ - }) +#define _mm_slli_si128(a, imm) \ + _sse2neon_define1( \ + __m128i, a, int8x16_t ret; \ + if (_sse2neon_unlikely(imm == 0)) ret = vreinterpretq_s8_m128i(_a); \ + else if (_sse2neon_unlikely((imm) & ~15)) ret = vdupq_n_s8(0); \ + else ret = vextq_s8(vdupq_n_s8(0), vreinterpretq_s8_m128i(_a), \ + ((imm <= 0 || imm > 15) ? 0 : (16 - imm))); \ + _sse2neon_return(vreinterpretq_m128i_s8(ret));) // Compute the square root of packed double-precision (64-bit) floating-point // elements in a, and store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_pd FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a))); #else double a0 = sqrt(((double *) &a)[0]); @@ -5175,7 +5261,7 @@ FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_sd FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return _mm_move_sd(a, _mm_sqrt_pd(b)); #else return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0])); @@ -5187,10 +5273,11 @@ FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sra_epi16 FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) { - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + int64_t c = vgetq_lane_s64(count, 0); if (_sse2neon_unlikely(c & ~15)) return _mm_cmplt_epi16(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); + return vreinterpretq_m128i_s16( + vshlq_s16((int16x8_t) a, vdupq_n_s16((int) -c))); } // Shift packed 32-bit integers in a right by count while shifting in sign bits, @@ -5198,10 +5285,11 @@ FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sra_epi32 FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) { - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + int64_t c = vgetq_lane_s64(count, 0); if (_sse2neon_unlikely(c & ~31)) return _mm_cmplt_epi32(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); + return vreinterpretq_m128i_s32( + vshlq_s32((int32x4_t) a, vdupq_n_s32((int) -c))); } // Shift packed 16-bit integers in a right by imm8 while shifting in sign @@ -5217,20 +5305,17 @@ FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) // and store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srai_epi32 // FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srai_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (_sse2neon_unlikely((imm) == 0)) { \ - ret = a; \ - } else if (_sse2neon_likely(0 < (imm) && (imm) < 32)) { \ - ret = vreinterpretq_m128i_s32( \ - vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-(imm)))); \ - } else { \ - ret = vreinterpretq_m128i_s32( \ - vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ - } \ - ret; \ - }) +#define _mm_srai_epi32(a, imm) \ + _sse2neon_define0( \ + __m128i, a, __m128i ret; if (_sse2neon_unlikely((imm) == 0)) { \ + ret = _a; \ + } else if (_sse2neon_likely(0 < (imm) && (imm) < 32)) { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_s32(vreinterpretq_s32_m128i(_a), vdupq_n_s32(-(imm)))); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(_a), 31)); \ + } _sse2neon_return(ret);) // Shift packed 16-bit integers in a right by count while shifting in zeros, and // store the results in dst. @@ -5274,62 +5359,50 @@ FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) // Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and // store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi16 -#define _mm_srli_epi16(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (_sse2neon_unlikely((imm) & ~15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_u16( \ - vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-(imm)))); \ - } \ - ret; \ - }) +#define _mm_srli_epi16(a, imm) \ + _sse2neon_define0( \ + __m128i, a, __m128i ret; if (_sse2neon_unlikely((imm) & ~15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u16( \ + vshlq_u16(vreinterpretq_u16_m128i(_a), vdupq_n_s16(-(imm)))); \ + } _sse2neon_return(ret);) // Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and // store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi32 // FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srli_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (_sse2neon_unlikely((imm) & ~31)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_u32( \ - vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-(imm)))); \ - } \ - ret; \ - }) +#define _mm_srli_epi32(a, imm) \ + _sse2neon_define0( \ + __m128i, a, __m128i ret; if (_sse2neon_unlikely((imm) & ~31)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u32( \ + vshlq_u32(vreinterpretq_u32_m128i(_a), vdupq_n_s32(-(imm)))); \ + } _sse2neon_return(ret);) // Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and // store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi64 -#define _mm_srli_epi64(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (_sse2neon_unlikely((imm) & ~63)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_u64( \ - vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-(imm)))); \ - } \ - ret; \ - }) +#define _mm_srli_epi64(a, imm) \ + _sse2neon_define0( \ + __m128i, a, __m128i ret; if (_sse2neon_unlikely((imm) & ~63)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u64( \ + vshlq_u64(vreinterpretq_u64_m128i(_a), vdupq_n_s64(-(imm)))); \ + } _sse2neon_return(ret);) // Shift a right by imm8 bytes while shifting in zeros, and store the results in // dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_si128 -#define _mm_srli_si128(a, imm) \ - __extension__({ \ - int8x16_t ret; \ - if (_sse2neon_unlikely((imm) & ~15)) \ - ret = vdupq_n_s8(0); \ - else \ - ret = vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), \ - (imm > 15 ? 0 : imm)); \ - vreinterpretq_m128i_s8(ret); \ - }) +#define _mm_srli_si128(a, imm) \ + _sse2neon_define1( \ + __m128i, a, int8x16_t ret; \ + if (_sse2neon_unlikely((imm) & ~15)) ret = vdupq_n_s8(0); \ + else ret = vextq_s8(vreinterpretq_s8_m128i(_a), vdupq_n_s8(0), \ + (imm > 15 ? 0 : imm)); \ + _sse2neon_return(vreinterpretq_m128i_s8(ret));) // Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point // elements) from a into memory. mem_addr must be aligned on a 16-byte boundary @@ -5337,7 +5410,7 @@ FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_pd FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); #else vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); @@ -5350,7 +5423,7 @@ FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_pd1 FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); @@ -5366,7 +5439,7 @@ FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=mm_store_sd FORCE_INLINE void _mm_store_sd(double *mem_addr, __m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); #else vst1_u64((uint64_t *) mem_addr, vget_low_u64(vreinterpretq_u64_m128d(a))); @@ -5392,7 +5465,7 @@ FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeh_pd FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); #else vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); @@ -5411,7 +5484,7 @@ FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storel_pd FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); #else vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); @@ -5461,8 +5534,8 @@ FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a) FORCE_INLINE void _mm_stream_pd(double *p, __m128d a) { #if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, (float32x4_t *) p); -#elif defined(__aarch64__) + __builtin_nontemporal_store(a, (__m128d *) p); +#elif defined(__aarch64__) || defined(_M_ARM64) vst1q_f64(p, vreinterpretq_f64_m128d(a)); #else vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a)); @@ -5542,7 +5615,7 @@ FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=mm_sub_pd FORCE_INLINE __m128d _mm_sub_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vsubq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -5625,6 +5698,9 @@ FORCE_INLINE __m128d _mm_undefined_pd(void) #pragma GCC diagnostic ignored "-Wuninitialized" #endif __m128d a; +#if defined(_MSC_VER) + a = _mm_setzero_pd(); +#endif return a; #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop @@ -5636,7 +5712,7 @@ FORCE_INLINE __m128d _mm_undefined_pd(void) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi16 FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s16( vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); #else @@ -5652,7 +5728,7 @@ FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi32 FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s32( vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); #else @@ -5668,7 +5744,7 @@ FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi64 FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s64( vzip2q_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); #else @@ -5683,7 +5759,7 @@ FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi8 FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s8( vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); #else @@ -5701,7 +5777,7 @@ FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_pd FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -5716,7 +5792,7 @@ FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi16 FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s16( vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); #else @@ -5732,7 +5808,7 @@ FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi32 FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s32( vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); #else @@ -5748,7 +5824,7 @@ FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi64 FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s64( vzip1q_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); #else @@ -5763,7 +5839,7 @@ FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi8 FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s8( vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); #else @@ -5779,7 +5855,7 @@ FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_pd FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -5816,7 +5892,7 @@ FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b) { _sse2neon_const __m128d mask = _mm_set_pd(1.0f, -1.0f); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(mask))); @@ -5832,7 +5908,8 @@ FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b) FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) { _sse2neon_const __m128 mask = _mm_setr_ps(-1.0f, 1.0f, -1.0f, 1.0f); -#if defined(__aarch64__) || defined(__ARM_FEATURE_FMA) /* VFPv4+ */ +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_FMA) /* VFPv4+ */ return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(mask), vreinterpretq_f32_m128(b))); @@ -5846,7 +5923,7 @@ FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_hadd_pd FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else @@ -5862,7 +5939,7 @@ FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_hadd_ps FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); #else @@ -5880,7 +5957,7 @@ FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_hsub_pd FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float64x2_t a = vreinterpretq_f64_m128d(_a); float64x2_t b = vreinterpretq_f64_m128d(_b); return vreinterpretq_m128d_f64( @@ -5900,7 +5977,7 @@ FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) { float32x4_t a = vreinterpretq_f32_m128(_a); float32x4_t b = vreinterpretq_f32_m128(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vsubq_f32(vuzp1q_f32(a, b), vuzp2q_f32(a, b))); #else @@ -5925,7 +6002,7 @@ FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_movedup_pd FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64( vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); #else @@ -5939,7 +6016,7 @@ FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_movehdup_ps FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vtrn2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a))); #elif defined(_sse2neon_shuffle) @@ -5958,7 +6035,7 @@ FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_moveldup_ps FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128_f32( vtrn1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a))); #elif defined(_sse2neon_shuffle) @@ -6025,6 +6102,7 @@ FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) // Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift // the result right by imm8 bytes, and store the low 16 bytes in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_alignr_epi8 +#if defined(__GNUC__) && !defined(__clang__) #define _mm_alignr_epi8(a, b, imm) \ __extension__({ \ uint8x16_t _a = vreinterpretq_u8_m128i(a); \ @@ -6040,30 +6118,43 @@ FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) ret; \ }) +#else +#define _mm_alignr_epi8(a, b, imm) \ + _sse2neon_define2( \ + __m128i, a, b, uint8x16_t __a = vreinterpretq_u8_m128i(_a); \ + uint8x16_t __b = vreinterpretq_u8_m128i(_b); __m128i ret; \ + if (_sse2neon_unlikely((imm) & ~31)) ret = \ + vreinterpretq_m128i_u8(vdupq_n_u8(0)); \ + else if (imm >= 16) ret = \ + _mm_srli_si128(_a, imm >= 16 ? imm - 16 : 0); \ + else ret = \ + vreinterpretq_m128i_u8(vextq_u8(__b, __a, imm < 16 ? imm : 0)); \ + _sse2neon_return(ret);) + +#endif + // Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift // the result right by imm8 bytes, and store the low 8 bytes in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_alignr_pi8 #define _mm_alignr_pi8(a, b, imm) \ - __extension__({ \ - __m64 ret; \ - if (_sse2neon_unlikely((imm) >= 16)) { \ + _sse2neon_define2( \ + __m64, a, b, __m64 ret; if (_sse2neon_unlikely((imm) >= 16)) { \ ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ } else { \ - uint8x8_t tmp_low, tmp_high; \ + uint8x8_t tmp_low; \ + uint8x8_t tmp_high; \ if ((imm) >= 8) { \ const int idx = (imm) -8; \ - tmp_low = vreinterpret_u8_m64(a); \ + tmp_low = vreinterpret_u8_m64(_a); \ tmp_high = vdup_n_u8(0); \ ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ } else { \ const int idx = (imm); \ - tmp_low = vreinterpret_u8_m64(b); \ - tmp_high = vreinterpret_u8_m64(a); \ + tmp_low = vreinterpret_u8_m64(_b); \ + tmp_high = vreinterpret_u8_m64(_a); \ ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ } \ - } \ - ret; \ - }) + } _sse2neon_return(ret);) // Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the // signed 16-bit results in dst. @@ -6072,7 +6163,7 @@ FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) { int16x8_t a = vreinterpretq_s16_m128i(_a); int16x8_t b = vreinterpretq_s16_m128i(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); #else return vreinterpretq_m128i_s16( @@ -6088,7 +6179,7 @@ FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) { int32x4_t a = vreinterpretq_s32_m128i(_a); int32x4_t b = vreinterpretq_s32_m128i(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s32(vpaddq_s32(a, b)); #else return vreinterpretq_m128i_s32( @@ -6120,7 +6211,7 @@ FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_hadds_epi16 FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int16x8_t a = vreinterpretq_s16_m128i(_a); int16x8_t b = vreinterpretq_s16_m128i(_b); return vreinterpretq_s64_s16( @@ -6145,7 +6236,7 @@ FORCE_INLINE __m64 _mm_hadds_pi16(__m64 _a, __m64 _b) { int16x4_t a = vreinterpret_s16_m64(_a); int16x4_t b = vreinterpret_s16_m64(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpret_s64_s16(vqadd_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); #else int16x4x2_t res = vuzp_s16(a, b); @@ -6160,7 +6251,7 @@ FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) { int16x8_t a = vreinterpretq_s16_m128i(_a); int16x8_t b = vreinterpretq_s16_m128i(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s16( vsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); #else @@ -6176,7 +6267,7 @@ FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) { int32x4_t a = vreinterpretq_s32_m128i(_a); int32x4_t b = vreinterpretq_s32_m128i(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s32( vsubq_s32(vuzp1q_s32(a, b), vuzp2q_s32(a, b))); #else @@ -6192,7 +6283,7 @@ FORCE_INLINE __m64 _mm_hsub_pi16(__m64 _a, __m64 _b) { int16x4_t a = vreinterpret_s16_m64(_a); int16x4_t b = vreinterpret_s16_m64(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpret_m64_s16(vsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); #else int16x4x2_t c = vuzp_s16(a, b); @@ -6207,7 +6298,7 @@ FORCE_INLINE __m64 _mm_hsub_pi32(__m64 _a, __m64 _b) { int32x2_t a = vreinterpret_s32_m64(_a); int32x2_t b = vreinterpret_s32_m64(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpret_m64_s32(vsub_s32(vuzp1_s32(a, b), vuzp2_s32(a, b))); #else int32x2x2_t c = vuzp_s32(a, b); @@ -6222,7 +6313,7 @@ FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) { int16x8_t a = vreinterpretq_s16_m128i(_a); int16x8_t b = vreinterpretq_s16_m128i(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s16( vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); #else @@ -6238,7 +6329,7 @@ FORCE_INLINE __m64 _mm_hsubs_pi16(__m64 _a, __m64 _b) { int16x4_t a = vreinterpret_s16_m64(_a); int16x4_t b = vreinterpret_s16_m64(_b); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpret_m64_s16(vqsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); #else int16x4x2_t c = vuzp_s16(a, b); @@ -6253,7 +6344,7 @@ FORCE_INLINE __m64 _mm_hsubs_pi16(__m64 _a, __m64 _b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint8x16_t a = vreinterpretq_u8_m128i(_a); int8x16_t b = vreinterpretq_s8_m128i(_b); int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), @@ -6357,7 +6448,7 @@ FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b uint8x16_t idx_masked = vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); #elif defined(__GNUC__) int8x16_t ret; @@ -6403,7 +6494,7 @@ FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) // (b < 0) ? 0xFFFF : 0 uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); // (b == 0) ? 0xFFFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b)); #else int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0))); @@ -6432,7 +6523,7 @@ FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); // (b == 0) ? 0xFFFFFFFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b)); #else int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0))); @@ -6461,7 +6552,7 @@ FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); // (b == 0) ? 0xFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); #else int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); @@ -6490,7 +6581,7 @@ FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15)); // (b == 0) ? 0xFFFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b)); #else int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); @@ -6519,7 +6610,7 @@ FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31)); // (b == 0) ? 0xFFFFFFFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b)); #else int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); @@ -6548,7 +6639,7 @@ FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7)); // (b == 0) ? 0xFF : 0 -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b)); #else int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); @@ -6570,35 +6661,36 @@ FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_blend_epi16 // FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, // __constrange(0,255) int imm) -#define _mm_blend_epi16(a, b, imm) \ - __extension__({ \ - const uint16_t _mask[8] = {((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0}; \ - uint16x8_t _mask_vec = vld1q_u16(_mask); \ - uint16x8_t _a = vreinterpretq_u16_m128i(a); \ - uint16x8_t _b = vreinterpretq_u16_m128i(b); \ - vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ - }) +#define _mm_blend_epi16(a, b, imm) \ + _sse2neon_define2( \ + __m128i, a, b, \ + const uint16_t _mask[8] = \ + _sse2neon_init(((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0); \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t __a = vreinterpretq_u16_m128i(_a); \ + uint16x8_t __b = vreinterpretq_u16_m128i(_b); _sse2neon_return( \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, __b, __a)));) // Blend packed double-precision (64-bit) floating-point elements from a and b // using control mask imm8, and store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_blend_pd -#define _mm_blend_pd(a, b, imm) \ - __extension__({ \ - const uint64_t _mask[2] = { \ - ((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \ - ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \ - uint64x2_t _mask_vec = vld1q_u64(_mask); \ - uint64x2_t _a = vreinterpretq_u64_m128d(a); \ - uint64x2_t _b = vreinterpretq_u64_m128d(b); \ - vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \ - }) +#define _mm_blend_pd(a, b, imm) \ + _sse2neon_define2( \ + __m128d, a, b, \ + const uint64_t _mask[2] = \ + _sse2neon_init(((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \ + ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)); \ + uint64x2_t _mask_vec = vld1q_u64(_mask); \ + uint64x2_t __a = vreinterpretq_u64_m128d(_a); \ + uint64x2_t __b = vreinterpretq_u64_m128d(_b); _sse2neon_return( \ + vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, __b, __a)));) // Blend packed single-precision (32-bit) floating-point elements from a and b // using mask, and store the results in dst. @@ -6636,7 +6728,7 @@ FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask) { uint64x2_t mask = vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_m128d(_mask), 63)); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) float64x2_t a = vreinterpretq_f64_m128d(_a); float64x2_t b = vreinterpretq_f64_m128d(_b); return vreinterpretq_m128d_f64(vbslq_f64(mask, b, a)); @@ -6666,7 +6758,7 @@ FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ceil_pd FORCE_INLINE __m128d _mm_ceil_pd(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vrndpq_f64(vreinterpretq_f64_m128d(a))); #else double *f = (double *) &a; @@ -6680,7 +6772,8 @@ FORCE_INLINE __m128d _mm_ceil_pd(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ceil_ps FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); #else float *f = (float *) &a; @@ -6712,7 +6805,7 @@ FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b) // in dst FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_u64( vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); #else @@ -6837,7 +6930,7 @@ FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) return vreinterpretq_m128i_u32(u32x4); } -// Zero extend packed unsigned 8-bit integers in the low 8 byte sof a to packed +// Zero extend packed unsigned 8-bit integers in the low 8 bytes of a to packed // 64-bit integers, and store the results in dst. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtepu8_epi64 FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) @@ -6869,7 +6962,7 @@ FORCE_INLINE __m128d _mm_dp_pd(__m128d a, __m128d b, const int imm) _mm_castsi128_pd(_mm_set_epi64x(bit5Mask, bit4Mask)); __m128d tmp = _mm_and_pd(mul, mulMask); #else -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) double d0 = (imm & 0x10) ? vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0) * vgetq_lane_f64(vreinterpretq_f64_m128d(b), 0) : 0; @@ -6883,7 +6976,7 @@ FORCE_INLINE __m128d _mm_dp_pd(__m128d a, __m128d b, const int imm) __m128d tmp = _mm_set_pd(d1, d0); #endif // Sum the products -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) double sum = vpaddd_f64(vreinterpretq_f64_m128d(tmp)); #else double sum = *((double *) &tmp) + *(((double *) &tmp) + 1); @@ -6901,42 +6994,46 @@ FORCE_INLINE __m128d _mm_dp_pd(__m128d a, __m128d b, const int imm) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_dp_ps FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) { -#if defined(__aarch64__) + float32x4_t elementwise_prod = _mm_mul_ps(a, b); + +#if defined(__aarch64__) || defined(_M_ARM64) /* shortcuts */ if (imm == 0xFF) { - return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b))); + return _mm_set1_ps(vaddvq_f32(elementwise_prod)); } - if (imm == 0x7F) { - float32x4_t m = _mm_mul_ps(a, b); - m[3] = 0; - return _mm_set1_ps(vaddvq_f32(m)); + + if ((imm & 0x0F) == 0x0F) { + if (!(imm & (1 << 4))) + elementwise_prod = vsetq_lane_f32(0.0f, elementwise_prod, 0); + if (!(imm & (1 << 5))) + elementwise_prod = vsetq_lane_f32(0.0f, elementwise_prod, 1); + if (!(imm & (1 << 6))) + elementwise_prod = vsetq_lane_f32(0.0f, elementwise_prod, 2); + if (!(imm & (1 << 7))) + elementwise_prod = vsetq_lane_f32(0.0f, elementwise_prod, 3); + + return _mm_set1_ps(vaddvq_f32(elementwise_prod)); } #endif - float s = 0, c = 0; - float32x4_t f32a = vreinterpretq_f32_m128(a); - float32x4_t f32b = vreinterpretq_f32_m128(b); + float s = 0.0f; - /* To improve the accuracy of floating-point summation, Kahan algorithm - * is used for each operation. - */ if (imm & (1 << 4)) - _sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]); + s += vgetq_lane_f32(elementwise_prod, 0); if (imm & (1 << 5)) - _sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]); + s += vgetq_lane_f32(elementwise_prod, 1); if (imm & (1 << 6)) - _sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]); + s += vgetq_lane_f32(elementwise_prod, 2); if (imm & (1 << 7)) - _sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]); - s += c; + s += vgetq_lane_f32(elementwise_prod, 3); - float32x4_t res = { - (imm & 0x1) ? s : 0, - (imm & 0x2) ? s : 0, - (imm & 0x4) ? s : 0, - (imm & 0x8) ? s : 0, + const float32_t res[4] = { + (imm & 0x1) ? s : 0.0f, + (imm & 0x2) ? s : 0.0f, + (imm & 0x4) ? s : 0.0f, + (imm & 0x8) ? s : 0.0f, }; - return vreinterpretq_m128_f32(res); + return vreinterpretq_m128_f32(vld1q_f32(res)); } // Extract a 32-bit integer from a, selected with imm8, and store the result in @@ -6969,7 +7066,7 @@ FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_floor_pd FORCE_INLINE __m128d _mm_floor_pd(__m128d a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128d_f64(vrndmq_f64(vreinterpretq_f64_m128d(a))); #else double *f = (double *) &a; @@ -6983,7 +7080,8 @@ FORCE_INLINE __m128d _mm_floor_pd(__m128d a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_floor_ps FORCE_INLINE __m128 _mm_floor_ps(__m128 a) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); #else float *f = (float *) &a; @@ -7016,56 +7114,50 @@ FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi32 // FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, // __constrange(0,4) int imm) -#define _mm_insert_epi32(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ - }) +#define _mm_insert_epi32(a, b, imm) \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))) // Copy a to dst, and insert the 64-bit integer i into dst at the location // specified by imm8. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi64 // FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, // __constrange(0,2) int imm) -#define _mm_insert_epi64(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s64( \ - vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ - }) +#define _mm_insert_epi64(a, b, imm) \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))) // Copy a to dst, and insert the lower 8-bit integer from i into dst at the // location specified by imm8. // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi8 // FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, // __constrange(0,16) int imm) -#define _mm_insert_epi8(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s8( \ - vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ - }) +#define _mm_insert_epi8(a, b, imm) \ + vreinterpretq_m128i_s8(vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))) // Copy a to tmp, then insert a single-precision (32-bit) floating-point // element from b into tmp using the control in imm8. Store tmp to dst using // the mask in imm8 (elements are zeroed out when the corresponding bit is set). // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=insert_ps -#define _mm_insert_ps(a, b, imm8) \ - __extension__({ \ - float32x4_t tmp1 = \ - vsetq_lane_f32(vgetq_lane_f32(b, (imm8 >> 6) & 0x3), \ - vreinterpretq_f32_m128(a), 0); \ - float32x4_t tmp2 = \ - vsetq_lane_f32(vgetq_lane_f32(tmp1, 0), vreinterpretq_f32_m128(a), \ - ((imm8 >> 4) & 0x3)); \ - const uint32_t data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, \ - ((imm8) & (1 << 1)) ? UINT32_MAX : 0, \ - ((imm8) & (1 << 2)) ? UINT32_MAX : 0, \ - ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; \ - uint32x4_t mask = vld1q_u32(data); \ - float32x4_t all_zeros = vdupq_n_f32(0); \ - \ - vreinterpretq_m128_f32( \ - vbslq_f32(mask, all_zeros, vreinterpretq_f32_m128(tmp2))); \ - }) +#define _mm_insert_ps(a, b, imm8) \ + _sse2neon_define2( \ + __m128, a, b, \ + float32x4_t tmp1 = \ + vsetq_lane_f32(vgetq_lane_f32(_b, (imm8 >> 6) & 0x3), \ + vreinterpretq_f32_m128(_a), 0); \ + float32x4_t tmp2 = \ + vsetq_lane_f32(vgetq_lane_f32(tmp1, 0), \ + vreinterpretq_f32_m128(_a), ((imm8 >> 4) & 0x3)); \ + const uint32_t data[4] = \ + _sse2neon_init(((imm8) & (1 << 0)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 1)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 2)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 3)) ? UINT32_MAX : 0); \ + uint32x4_t mask = vld1q_u32(data); \ + float32x4_t all_zeros = vdupq_n_f32(0); \ + \ + _sse2neon_return(vreinterpretq_m128_f32( \ + vbslq_f32(mask, all_zeros, vreinterpretq_f32_m128(tmp2))));) // Compare packed signed 32-bit integers in a and b, and store packed maximum // values in dst. @@ -7146,7 +7238,7 @@ FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a) { __m128i dst; uint16_t min, idx = 0; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) // Find the minimum value min = vminvq_u16(vreinterpretq_u16_m128i(a)); @@ -7208,6 +7300,8 @@ FORCE_INLINE __m128i _mm_mpsadbw_epu8(__m128i a, __m128i b, const int imm) default: #if defined(__GNUC__) || defined(__clang__) __builtin_unreachable(); +#elif defined(_MSC_VER) + __assume(0); #endif break; } @@ -7232,6 +7326,8 @@ FORCE_INLINE __m128i _mm_mpsadbw_epu8(__m128i a, __m128i b, const int imm) default: #if defined(__GNUC__) || defined(__clang__) __builtin_unreachable(); +#elif defined(_MSC_VER) + __assume(0); #endif break; } @@ -7245,7 +7341,7 @@ FORCE_INLINE __m128i _mm_mpsadbw_epu8(__m128i a, __m128i b, const int imm) c26 = vreinterpretq_s16_u16(vabdl_u8(vget_low_u8(_a_2), low_b)); uint8x16_t _a_3 = vextq_u8(_a, _a, 3); c37 = vreinterpretq_s16_u16(vabdl_u8(vget_low_u8(_a_3), low_b)); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) // |0|4|2|6| c04 = vpaddq_s16(c04, c26); // |1|5|3|7| @@ -7305,7 +7401,7 @@ FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_round_pd FORCE_INLINE __m128d _mm_round_pd(__m128d a, int rounding) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) switch (rounding) { case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): return vreinterpretq_m128d_f64(vrndnq_f64(vreinterpretq_f64_m128d(a))); @@ -7374,7 +7470,8 @@ FORCE_INLINE __m128d _mm_round_pd(__m128d a, int rounding) // software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) { -#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) +#if (defined(__aarch64__) || defined(_M_ARM64)) || \ + defined(__ARM_FEATURE_DIRECTED_ROUNDING) switch (rounding) { case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); @@ -7539,10 +7636,10 @@ FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) /* SSE4.2 */ -const static uint16_t _sse2neon_cmpestr_mask16b[8] ALIGN_STRUCT(16) = { +static const uint16_t ALIGN_STRUCT(16) _sse2neon_cmpestr_mask16b[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, }; -const static uint8_t _sse2neon_cmpestr_mask8b[16] ALIGN_STRUCT(16) = { +static const uint8_t ALIGN_STRUCT(16) _sse2neon_cmpestr_mask8b[16] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, }; @@ -7808,7 +7905,7 @@ static int _sse2neon_aggregate_ranges_16x8(int la, int lb, __m128i mtx[16]) vshrq_n_u32(vreinterpretq_u32_m128i(mtx[j]), 16)); uint32x4_t vec_res = vandq_u32(vreinterpretq_u32_m128i(mtx[j]), vreinterpretq_u32_m128i(tmp)); -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) int t = vaddvq_u32(vec_res) ? 1 : 0; #else uint64x2_t sumh = vpaddlq_u32(vec_res); @@ -8007,10 +8104,10 @@ FORCE_INLINE int _sse2neon_sido_negative(int res, int lb, int imm8, int bound) FORCE_INLINE int _sse2neon_clz(unsigned int x) { -#if _MSC_VER - DWORD cnt = 0; - if (_BitScanForward(&cnt, x)) - return cnt; +#ifdef _MSC_VER + unsigned long cnt = 0; + if (_BitScanReverse(&cnt, x)) + return 31 - cnt; return 32; #else return x != 0 ? __builtin_clz(x) : 32; @@ -8019,10 +8116,10 @@ FORCE_INLINE int _sse2neon_clz(unsigned int x) FORCE_INLINE int _sse2neon_ctz(unsigned int x) { -#if _MSC_VER - DWORD cnt = 0; - if (_BitScanReverse(&cnt, x)) - return 31 - cnt; +#ifdef _MSC_VER + unsigned long cnt = 0; + if (_BitScanForward(&cnt, x)) + return cnt; return 32; #else return x != 0 ? __builtin_ctz(x) : 32; @@ -8031,20 +8128,19 @@ FORCE_INLINE int _sse2neon_ctz(unsigned int x) FORCE_INLINE int _sse2neon_ctzll(unsigned long long x) { -#if _MSC_VER +#ifdef _MSC_VER unsigned long cnt; -#ifdef defined(SSE2NEON_HAS_BITSCAN64) - (defined(_M_AMD64) || defined(__x86_64__)) - if((_BitScanForward64(&cnt, x)) - return (int)(cnt); +#if defined(SSE2NEON_HAS_BITSCAN64) + if (_BitScanForward64(&cnt, x)) + return (int) (cnt); #else if (_BitScanForward(&cnt, (unsigned long) (x))) return (int) cnt; if (_BitScanForward(&cnt, (unsigned long) (x >> 32))) return (int) (cnt + 32); -#endif +#endif /* SSE2NEON_HAS_BITSCAN64 */ return 64; -#else +#else /* assume GNU compatible compilers */ return x != 0 ? __builtin_ctzll(x) : 64; #endif } @@ -8178,6 +8274,9 @@ FORCE_INLINE int _mm_cmpestrs(__m128i a, int lb, const int imm8) { + (void) a; + (void) b; + (void) lb; SSE2NEON_CMPSTR_SET_UPPER(bound, imm8); return la <= (bound - 1); } @@ -8191,6 +8290,9 @@ FORCE_INLINE int _mm_cmpestrz(__m128i a, int lb, const int imm8) { + (void) a; + (void) b; + (void) la; SSE2NEON_CMPSTR_SET_UPPER(bound, imm8); return lb <= (bound - 1); } @@ -8272,6 +8374,7 @@ FORCE_INLINE int _mm_cmpistro(__m128i a, __m128i b, const int imm8) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpistrs FORCE_INLINE int _mm_cmpistrs(__m128i a, __m128i b, const int imm8) { + (void) b; SSE2NEON_CMPSTR_SET_UPPER(bound, imm8); int la; SSE2NEON_CMPISTRX_LENGTH(a, la, imm8); @@ -8283,6 +8386,7 @@ FORCE_INLINE int _mm_cmpistrs(__m128i a, __m128i b, const int imm8) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpistrz FORCE_INLINE int _mm_cmpistrz(__m128i a, __m128i b, const int imm8) { + (void) a; SSE2NEON_CMPSTR_SET_UPPER(bound, imm8); int lb; SSE2NEON_CMPISTRX_LENGTH(b, lb, imm8); @@ -8293,7 +8397,7 @@ FORCE_INLINE int _mm_cmpistrz(__m128i a, __m128i b, const int imm8) // in b for greater than. FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) return vreinterpretq_m128i_u64( vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); #else @@ -8312,7 +8416,8 @@ FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" : [c] "+r"(crc) : [v] "r"(v)); -#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) +#elif ((__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32)) || \ + (defined(_M_ARM64) && !defined(__clang__)) crc = __crc32ch(crc, v); #else crc = _mm_crc32_u8(crc, v & 0xff); @@ -8330,7 +8435,8 @@ FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" : [c] "+r"(crc) : [v] "r"(v)); -#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) +#elif ((__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32)) || \ + (defined(_M_ARM64) && !defined(__clang__)) crc = __crc32cw(crc, v); #else crc = _mm_crc32_u16(crc, v & 0xffff); @@ -8348,6 +8454,8 @@ FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" : [c] "+r"(crc) : [v] "r"(v)); +#elif (defined(_M_ARM64) && !defined(__clang__)) + crc = __crc32cd((uint32_t) crc, v); #else crc = _mm_crc32_u32((uint32_t) (crc), v & 0xffffffff); crc = _mm_crc32_u32((uint32_t) (crc), (v >> 32) & 0xffffffff); @@ -8364,7 +8472,8 @@ FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" : [c] "+r"(crc) : [v] "r"(v)); -#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) +#elif ((__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32)) || \ + (defined(_M_ARM64) && !defined(__clang__)) crc = __crc32cb(crc, v); #else crc ^= v; @@ -8380,7 +8489,7 @@ FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) /* AES */ -#if !defined(__ARM_FEATURE_CRYPTO) +#if !defined(__ARM_FEATURE_CRYPTO) && (!defined(_M_ARM64) || defined(__clang__)) /* clang-format off */ #define SSE2NEON_AES_SBOX(w) \ { \ @@ -8471,7 +8580,7 @@ static const uint8_t _sse2neon_rsbox[256] = SSE2NEON_AES_RSBOX(SSE2NEON_AES_H0); #undef SSE2NEON_AES_H0 /* x_time function and matrix multiply function */ -#if !defined(__aarch64__) +#if !defined(__aarch64__) && !defined(_M_ARM64) #define SSE2NEON_XT(x) (((x) << 1) ^ ((((x) >> 7) & 1) * 0x1b)) #define SSE2NEON_MULTIPLY(x, y) \ (((y & 1) * x) ^ ((y >> 1 & 1) * SSE2NEON_XT(x)) ^ \ @@ -8487,7 +8596,7 @@ static const uint8_t _sse2neon_rsbox[256] = SSE2NEON_AES_RSBOX(SSE2NEON_AES_H0); // for more information. FORCE_INLINE __m128i _mm_aesenc_si128(__m128i a, __m128i RoundKey) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) static const uint8_t shift_rows[] = { 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3, 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb, @@ -8607,7 +8716,7 @@ FORCE_INLINE __m128i _mm_aesdec_si128(__m128i a, __m128i RoundKey) v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(_sse2neon_rsbox + 0xc0), w - 0xc0); // inverse mix columns - // muliplying 'v' by 4 in GF(2^8) + // multiplying 'v' by 4 in GF(2^8) w = (v << 1) ^ (uint8x16_t) (((int8x16_t) v >> 7) & 0x1b); w = (w << 1) ^ (uint8x16_t) (((int8x16_t) w >> 7) & 0x1b); v ^= w; @@ -8837,9 +8946,9 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) // for more details. FORCE_INLINE __m128i _mm_aesenc_si128(__m128i a, __m128i b) { - return vreinterpretq_m128i_u8( - vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))) ^ - vreinterpretq_u8_m128i(b)); + return vreinterpretq_m128i_u8(veorq_u8( + vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))), + vreinterpretq_u8_m128i(b))); } // Perform one round of an AES decryption flow on data (state) in a using the @@ -8868,8 +8977,8 @@ FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) FORCE_INLINE __m128i _mm_aesdeclast_si128(__m128i a, __m128i RoundKey) { return vreinterpretq_m128i_u8( - vaesdq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0)) ^ - vreinterpretq_u8_m128i(RoundKey)); + veorq_u8(vaesdq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0)), + vreinterpretq_u8_m128i(RoundKey))); } // Perform the InvMixColumns transformation on a and store the result in dst. @@ -8888,6 +8997,7 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) // AESE does ShiftRows and SubBytes on A uint8x16_t u8 = vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0)); +#ifndef _MSC_VER uint8x16_t dest = { // Undo ShiftRows step from AESE and extract X1 and X3 u8[0x4], u8[0x1], u8[0xE], u8[0xB], // SubBytes(X1) @@ -8897,6 +9007,33 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) }; uint32x4_t r = {0, (unsigned) rcon, 0, (unsigned) rcon}; return vreinterpretq_m128i_u8(dest) ^ vreinterpretq_m128i_u32(r); +#else + // We have to do this hack because MSVC is strictly adhering to the CPP + // standard, in particular C++03 8.5.1 sub-section 15, which states that + // unions must be initialized by their first member type. + + // As per the Windows ARM64 ABI, it is always little endian, so this works + __n128 dest{ + ((uint64_t) u8.n128_u8[0x4] << 0) | ((uint64_t) u8.n128_u8[0x1] << 8) | + ((uint64_t) u8.n128_u8[0xE] << 16) | + ((uint64_t) u8.n128_u8[0xB] << 24) | + ((uint64_t) u8.n128_u8[0x1] << 32) | + ((uint64_t) u8.n128_u8[0xE] << 40) | + ((uint64_t) u8.n128_u8[0xB] << 48) | + ((uint64_t) u8.n128_u8[0x4] << 56), + ((uint64_t) u8.n128_u8[0xC] << 0) | ((uint64_t) u8.n128_u8[0x9] << 8) | + ((uint64_t) u8.n128_u8[0x6] << 16) | + ((uint64_t) u8.n128_u8[0x3] << 24) | + ((uint64_t) u8.n128_u8[0x9] << 32) | + ((uint64_t) u8.n128_u8[0x6] << 40) | + ((uint64_t) u8.n128_u8[0x3] << 48) | + ((uint64_t) u8.n128_u8[0xC] << 56)}; + + dest.n128_u32[1] = dest.n128_u32[1] ^ rcon; + dest.n128_u32[3] = dest.n128_u32[3] ^ rcon; + + return dest; +#endif } #endif @@ -8927,19 +9064,19 @@ FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) } } -FORCE_INLINE unsigned int _sse2neon_mm_get_denormals_zero_mode() +FORCE_INLINE unsigned int _sse2neon_mm_get_denormals_zero_mode(void) { union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif @@ -8952,9 +9089,11 @@ FORCE_INLINE unsigned int _sse2neon_mm_get_denormals_zero_mode() // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_popcnt_u32 FORCE_INLINE int _mm_popcnt_u32(unsigned int a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) #if __has_builtin(__builtin_popcount) return __builtin_popcount(a); +#elif defined(_MSC_VER) + return _CountOneBits(a); #else return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); #endif @@ -8979,9 +9118,11 @@ FORCE_INLINE int _mm_popcnt_u32(unsigned int a) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_popcnt_u64 FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) #if __has_builtin(__builtin_popcountll) return __builtin_popcountll(a); +#elif defined(_MSC_VER) + return _CountOneBits64(a); #else return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); #endif @@ -9008,23 +9149,23 @@ FORCE_INLINE void _sse2neon_mm_set_denormals_zero_mode(unsigned int flag) // regardless of the value of the FZ bit. union { fpcr_bitfield field; -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t value; #else uint32_t value; #endif } r; -#if defined(__aarch64__) - __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#if defined(__aarch64__) || defined(_M_ARM64) + r.value = _sse2neon_get_fpcr(); #else __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ #endif r.field.bit24 = (flag & _MM_DENORMALS_ZERO_MASK) == _MM_DENORMALS_ZERO_ON; -#if defined(__aarch64__) - __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#if defined(__aarch64__) || defined(_M_ARM64) + _sse2neon_set_fpcr(r.value); #else __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ #endif @@ -9034,7 +9175,7 @@ FORCE_INLINE void _sse2neon_mm_set_denormals_zero_mode(unsigned int flag) // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=rdtsc FORCE_INLINE uint64_t _rdtsc(void) { -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(_M_ARM64) uint64_t val; /* According to ARM DDI 0487F.c, from Armv8.0 to Armv8.5 inclusive, the @@ -9043,7 +9184,11 @@ FORCE_INLINE uint64_t _rdtsc(void) * bits wide and it is attributed with the flag 'cap_user_time_short' * is true. */ +#if defined(_MSC_VER) + val = _ReadStatusReg(ARM64_SYSREG(3, 3, 14, 0, 2)); +#else __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(val)); +#endif return val; #else From 705a7eac0c0ccb12df1c6f8b35b4512c9e1549fb Mon Sep 17 00:00:00 2001 From: SChernykh Date: Tue, 14 Nov 2023 13:06:10 +0100 Subject: [PATCH 56/87] Updated pricing record size for Zephyr solo mining --- src/base/tools/cryptonote/BlockTemplate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 1926136b..bc5e2a93 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -198,7 +198,7 @@ bool xmrig::BlockTemplate::parse(bool hashes) } if (m_coin == Coin::ZEPHYR) { - uint8_t pricing_record[24]; + uint8_t pricing_record[120]; ar(pricing_record); } From 0b59b7eb430fb843bbc37dced8f14625d91057f3 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Wed, 15 Nov 2023 16:18:05 +0100 Subject: [PATCH 57/87] Zephyr solo mining: handle multiple outputs --- src/base/tools/cryptonote/BlockTemplate.cpp | 40 ++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index bc5e2a93..1a26a914 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -225,8 +225,12 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_height); ar(m_numOutputs); - const uint64_t expected_outputs = (m_coin == Coin::ZEPHYR) ? 2 : 1; - if (m_numOutputs != expected_outputs) { + if (m_coin == Coin::ZEPHYR) { + if (m_numOutputs < 2) { + return false; + } + } + else if (m_numOutputs != 1) { return false; } @@ -252,23 +256,25 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar.skip(asset_type_len); ar(m_viewTag); - uint64_t amount2; - ar(amount2); + for (uint64_t k = 1; k < m_numOutputs; ++k) { + uint64_t amount2; + ar(amount2); - uint8_t output_type2; - ar(output_type2); - if (output_type2 != 2) { - return false; + uint8_t output_type2; + ar(output_type2); + if (output_type2 != 2) { + return false; + } + + Span key2; + ar(key2, kKeySize); + + ar(asset_type_len); + ar.skip(asset_type_len); + + uint8_t view_tag2; + ar(view_tag2); } - - Span key2; - ar(key2, kKeySize); - - ar(asset_type_len); - ar.skip(asset_type_len); - - uint8_t view_tag2; - ar(view_tag2); } else if (m_outputType == 3) { ar(m_viewTag); From 4bda6e054d6b2d5bc429e0266b813fe25dbe0f62 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 23 Nov 2023 19:51:41 +0700 Subject: [PATCH 58/87] v6.21.0-dev --- CHANGELOG.md | 10 ++++++++++ src/version.h | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d81c7c4e..48c52131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v6.21.0 +- [#3302](https://github.com/xmrig/xmrig/pull/3302) [#3312](https://github.com/xmrig/xmrig/pull/3312) Enabled keepalive for Windows (>= Vista). +- [#3320](https://github.com/xmrig/xmrig/pull/3320) Added "built for OS/architecture/bits" to "ABOUT". +- [#3339](https://github.com/xmrig/xmrig/pull/3339) Added SNI option for TLS connections. +- [#3342](https://github.com/xmrig/xmrig/pull/3342) Update `cn_main_loop.asm`. +- [#3346](https://github.com/xmrig/xmrig/pull/3346) ARM64 JIT: don't use `x18` register. +- [#3348](https://github.com/xmrig/xmrig/pull/3348) Update to latest `sse2neon.h`. +- [#3356](https://github.com/xmrig/xmrig/pull/3356) Updated pricing record size for **Zephyr** solo mining. +- [#3358](https://github.com/xmrig/xmrig/pull/3358) **Zephyr** solo mining: handle multiple outputs. + # v6.20.0 - Added new ARM CPU names. - [#2394](https://github.com/xmrig/xmrig/pull/2394) Added new CMake options `ARM_V8` and `ARM_V7`. diff --git a/src/version.h b/src/version.h index 5bf1b2f5..7e2b085a 100644 --- a/src/version.h +++ b/src/version.h @@ -22,15 +22,15 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.20.1-dev" +#define APP_VERSION "6.21.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 6 -#define APP_VER_MINOR 20 -#define APP_VER_PATCH 1 +#define APP_VER_MINOR 21 +#define APP_VER_PATCH 0 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 8084ff37a5c8935c649a2e362da0fe570c79a2c2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 23 Nov 2023 20:40:58 +0700 Subject: [PATCH 59/87] v6.21.0 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 7e2b085a..a2bf3317 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.0-dev" +#define APP_VERSION "6.21.0" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" From 592b0c9c76f07a6e172880e4e63e86fcf8769615 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 23 Nov 2023 21:19:36 +0700 Subject: [PATCH 60/87] v6.21.1-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index a2bf3317..a2a2e13d 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.0" +#define APP_VERSION "6.21.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 21 -#define APP_VER_PATCH 0 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From c50369d65d42555a4330dbeb973f2a433ed2c55d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 23 Dec 2023 15:31:05 +0000 Subject: [PATCH 61/87] add support for townforge (monero fork using randomx) --- src/base/crypto/Coin.cpp | 1 + src/base/crypto/Coin.h | 1 + src/base/tools/cryptonote/BlockTemplate.cpp | 10 ++++++- src/base/tools/cryptonote/WalletAddress.cpp | 33 +++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/base/crypto/Coin.cpp b/src/base/crypto/Coin.cpp index 2508e9cc..c528acec 100644 --- a/src/base/crypto/Coin.cpp +++ b/src/base/crypto/Coin.cpp @@ -54,6 +54,7 @@ static const CoinInfo coinInfo[] = { { Algorithm::KAWPOW_RVN, "RVN", "Ravencoin", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " raven ") }, { Algorithm::RX_WOW, "WOW", "Wownero", 300, 100000000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " wownero ") }, { Algorithm::RX_0, "ZEPH", "Zephyr", 120, 1000000000000, BLUE_BG_BOLD( WHITE_BOLD_S " zephyr ") }, + { Algorithm::RX_0, "Townforge","Townforge", 30, 100000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " townforge ") }, }; diff --git a/src/base/crypto/Coin.h b/src/base/crypto/Coin.h index 166618b1..12ac1497 100644 --- a/src/base/crypto/Coin.h +++ b/src/base/crypto/Coin.h @@ -40,6 +40,7 @@ public: RAVEN, WOWNERO, ZEPHYR, + TOWNFORGE, MAX }; diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index 1a26a914..b0a6bd9d 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -207,7 +207,8 @@ bool xmrig::BlockTemplate::parse(bool hashes) setOffset(MINER_TX_PREFIX_OFFSET, ar.index()); ar(m_txVersion); - ar(m_unlockTime); + if (m_coin != Coin::TOWNFORGE) + ar(m_unlockTime); ar(m_numInputs); // must be 1 input @@ -280,6 +281,9 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_viewTag); } + if (m_coin == Coin::TOWNFORGE) + ar(m_unlockTime); + ar(m_extraSize); setOffset(TX_EXTRA_OFFSET, ar.index()); @@ -335,6 +339,10 @@ bool xmrig::BlockTemplate::parse(bool hashes) uint8_t vin_rct_type = 0; ar(vin_rct_type); + // no way I'm parsing a full game update here + if (m_coin == Coin::TOWNFORGE && m_height % 720 == 0) + return true; + // must be RCTTypeNull (0) if (vin_rct_type != 0) { return false; diff --git a/src/base/tools/cryptonote/WalletAddress.cpp b/src/base/tools/cryptonote/WalletAddress.cpp index f9b8a9f7..9e9a89e9 100644 --- a/src/base/tools/cryptonote/WalletAddress.cpp +++ b/src/base/tools/cryptonote/WalletAddress.cpp @@ -33,6 +33,26 @@ bool xmrig::WalletAddress::decode(const char *address, size_t size) { + uint64_t tf_tag = 0; + if (size >= 4 && !strncmp(address, "TF", 2)) + { + tf_tag = 0x424200; + switch (address[2]) + { + case '1': tf_tag |= 0; break; + case '2': tf_tag |= 1; break; + default: tf_tag = 0; return false; + } + switch (address[3]) { + case 'M': tf_tag |= 0; break; + case 'T': tf_tag |= 0x10; break; + case 'S': tf_tag |= 0x20; break; + default: tf_tag = 0; return false; + } + address += 4; + size -= 4; + } + static constexpr std::array block_sizes{ 0, 2, 3, 5, 6, 7, 9, 10, 11 }; static constexpr char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; constexpr size_t alphabet_size = sizeof(alphabet) - 1; @@ -114,6 +134,9 @@ bool xmrig::WalletAddress::decode(const char *address, size_t size) if (memcmp(m_checksum, md, sizeof(m_checksum)) == 0) { m_data = { address, size }; + if (tf_tag) + m_tag = tf_tag; + return true; } } @@ -228,6 +251,16 @@ const xmrig::WalletAddress::TagInfo &xmrig::WalletAddress::tagInfo(uint64_t tag) { 0x54, { Coin::GRAFT, TESTNET, PUBLIC, 28881, 28882 } }, { 0x55, { Coin::GRAFT, TESTNET, INTEGRATED, 28881, 28882 } }, { 0x70, { Coin::GRAFT, TESTNET, SUBADDRESS, 28881, 28882 } }, + + { 0x424200, { Coin::TOWNFORGE, MAINNET, PUBLIC, 18881, 18882 } }, + { 0x424201, { Coin::TOWNFORGE, MAINNET, SUBADDRESS, 18881, 18882 } }, + + { 0x424210, { Coin::TOWNFORGE, TESTNET, PUBLIC, 28881, 28882 } }, + { 0x424211, { Coin::TOWNFORGE, TESTNET, SUBADDRESS, 28881, 28882 } }, + + { 0x424220, { Coin::TOWNFORGE, STAGENET, PUBLIC, 38881, 38882 } }, + { 0x424221, { Coin::TOWNFORGE, STAGENET, SUBADDRESS, 38881, 38882 } }, + }; const auto it = tags.find(tag); From 07e1e77c4fb8fb06dab60ded22209f01e9132386 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 29 Dec 2023 21:17:19 +0700 Subject: [PATCH 62/87] Code style cleanup. --- src/base/tools/cryptonote/BlockTemplate.cpp | 15 ++++++++++----- src/base/tools/cryptonote/WalletAddress.cpp | 10 +++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/base/tools/cryptonote/BlockTemplate.cpp b/src/base/tools/cryptonote/BlockTemplate.cpp index b0a6bd9d..310fedf4 100644 --- a/src/base/tools/cryptonote/BlockTemplate.cpp +++ b/src/base/tools/cryptonote/BlockTemplate.cpp @@ -1,8 +1,8 @@ /* XMRig * Copyright (c) 2012-2013 The Cryptonote developers * Copyright (c) 2014-2021 The Monero Project - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -207,8 +207,11 @@ bool xmrig::BlockTemplate::parse(bool hashes) setOffset(MINER_TX_PREFIX_OFFSET, ar.index()); ar(m_txVersion); - if (m_coin != Coin::TOWNFORGE) + + if (m_coin != Coin::TOWNFORGE) { ar(m_unlockTime); + } + ar(m_numInputs); // must be 1 input @@ -281,8 +284,9 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(m_viewTag); } - if (m_coin == Coin::TOWNFORGE) + if (m_coin == Coin::TOWNFORGE) { ar(m_unlockTime); + } ar(m_extraSize); @@ -340,8 +344,9 @@ bool xmrig::BlockTemplate::parse(bool hashes) ar(vin_rct_type); // no way I'm parsing a full game update here - if (m_coin == Coin::TOWNFORGE && m_height % 720 == 0) + if (m_coin == Coin::TOWNFORGE && m_height % 720 == 0) { return true; + } // must be RCTTypeNull (0) if (vin_rct_type != 0) { diff --git a/src/base/tools/cryptonote/WalletAddress.cpp b/src/base/tools/cryptonote/WalletAddress.cpp index 9e9a89e9..3719031a 100644 --- a/src/base/tools/cryptonote/WalletAddress.cpp +++ b/src/base/tools/cryptonote/WalletAddress.cpp @@ -1,8 +1,8 @@ /* XMRig * Copyright (c) 2012-2013 The Cryptonote developers * Copyright (c) 2014-2021 The Monero Project - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2023 SChernykh + * Copyright (c) 2016-2023 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,8 +34,7 @@ bool xmrig::WalletAddress::decode(const char *address, size_t size) { uint64_t tf_tag = 0; - if (size >= 4 && !strncmp(address, "TF", 2)) - { + if (size >= 4 && !strncmp(address, "TF", 2)) { tf_tag = 0x424200; switch (address[2]) { @@ -134,8 +133,9 @@ bool xmrig::WalletAddress::decode(const char *address, size_t size) if (memcmp(m_checksum, md, sizeof(m_checksum)) == 0) { m_data = { address, size }; - if (tf_tag) + if (tf_tag) { m_tag = tf_tag; + } return true; } From 206295c6cb55bc646acd520091f238ed2b918f4b Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sat, 13 Jan 2024 20:14:08 +0100 Subject: [PATCH 63/87] Fixed Zephyr mining (OpenCL) --- src/backend/opencl/cl/rx/blake2b.cl | 87 + src/backend/opencl/cl/rx/randomx_cl.h | 4963 +++++++++-------- .../rx/Blake2bInitialHashDoubleKernel.cpp | 58 + .../rx/Blake2bInitialHashDoubleKernel.h | 50 + src/backend/opencl/opencl.cmake | 2 + .../opencl/runners/OclRxBaseRunner.cpp | 29 +- src/backend/opencl/runners/OclRxBaseRunner.h | 32 +- 7 files changed, 2759 insertions(+), 2462 deletions(-) create mode 100644 src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.cpp create mode 100644 src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h diff --git a/src/backend/opencl/cl/rx/blake2b.cl b/src/backend/opencl/cl/rx/blake2b.cl index b33e1206..a0084a00 100644 --- a/src/backend/opencl/cl/rx/blake2b.cl +++ b/src/backend/opencl/cl/rx/blake2b.cl @@ -138,6 +138,93 @@ __kernel void blake2b_initial_hash(__global void *out, __global const void* bloc t[7] = hash[7]; } +void blake2b_512_process_double_block_variable(ulong *out, ulong* m, __global const ulong* in, uint in_len, uint out_len) +{ + ulong v[16] = + { + iv0 ^ (0x01010000u | out_len), iv1, iv2, iv3, iv4 , iv5, iv6, iv7, + iv0 , iv1, iv2, iv3, iv4 ^ 128, iv5, iv6, iv7, + }; + + BLAKE2B_ROUNDS(); + + ulong h[8]; + v[0] = h[0] = v[0] ^ v[8] ^ iv0 ^ (0x01010000u | out_len); + v[1] = h[1] = v[1] ^ v[9] ^ iv1; + v[2] = h[2] = v[2] ^ v[10] ^ iv2; + v[3] = h[3] = v[3] ^ v[11] ^ iv3; + v[4] = h[4] = v[4] ^ v[12] ^ iv4; + v[5] = h[5] = v[5] ^ v[13] ^ iv5; + v[6] = h[6] = v[6] ^ v[14] ^ iv6; + v[7] = h[7] = v[7] ^ v[15] ^ iv7; + v[8] = iv0; + v[9] = iv1; + v[10] = iv2; + v[11] = iv3; + v[12] = iv4 ^ in_len; + v[13] = iv5; + v[14] = ~iv6; + v[15] = iv7; + + m[ 0] = (in_len > 128) ? in[16] : 0; + m[ 1] = (in_len > 136) ? in[17] : 0; + m[ 2] = (in_len > 144) ? in[18] : 0; + m[ 3] = (in_len > 152) ? in[19] : 0; + m[ 4] = (in_len > 160) ? in[20] : 0; + m[ 5] = (in_len > 168) ? in[21] : 0; + m[ 6] = (in_len > 176) ? in[22] : 0; + m[ 7] = (in_len > 184) ? in[23] : 0; + m[ 8] = (in_len > 192) ? in[24] : 0; + m[ 9] = (in_len > 200) ? in[25] : 0; + m[10] = (in_len > 208) ? in[26] : 0; + m[11] = (in_len > 216) ? in[27] : 0; + m[12] = (in_len > 224) ? in[28] : 0; + m[13] = (in_len > 232) ? in[29] : 0; + m[14] = (in_len > 240) ? in[30] : 0; + m[15] = (in_len > 248) ? in[31] : 0; + + if (in_len % sizeof(ulong)) + m[(in_len - 128) / sizeof(ulong)] &= (ulong)(-1) >> (64 - (in_len % sizeof(ulong)) * 8); + + BLAKE2B_ROUNDS(); + + if (out_len > 0) out[0] = h[0] ^ v[0] ^ v[8]; + if (out_len > 8) out[1] = h[1] ^ v[1] ^ v[9]; + if (out_len > 16) out[2] = h[2] ^ v[2] ^ v[10]; + if (out_len > 24) out[3] = h[3] ^ v[3] ^ v[11]; + if (out_len > 32) out[4] = h[4] ^ v[4] ^ v[12]; + if (out_len > 40) out[5] = h[5] ^ v[5] ^ v[13]; + if (out_len > 48) out[6] = h[6] ^ v[6] ^ v[14]; + if (out_len > 56) out[7] = h[7] ^ v[7] ^ v[15]; +} + +__attribute__((reqd_work_group_size(64, 1, 1))) +__kernel void blake2b_initial_hash_double(__global void *out, __global const void* blockTemplate, uint blockTemplateSize, uint start_nonce) +{ + const uint global_index = get_global_id(0); + + __global const ulong* p = (__global const ulong*) blockTemplate; + + ulong m[16] = { p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] }; + + const ulong nonce = start_nonce + global_index; + m[4] = (m[4] & ((ulong)(-1) >> 8)) | (nonce << 56); + m[5] = (m[5] & ((ulong)(-1) << 24)) | (nonce >> 8); + + ulong hash[8]; + blake2b_512_process_double_block_variable(hash, m, p, blockTemplateSize, 64); + + __global ulong* t = ((__global ulong*) out) + global_index * 8; + t[0] = hash[0]; + t[1] = hash[1]; + t[2] = hash[2]; + t[3] = hash[3]; + t[4] = hash[4]; + t[5] = hash[5]; + t[6] = hash[6]; + t[7] = hash[7]; +} + #define in_len 256 #define out_len 32 diff --git a/src/backend/opencl/cl/rx/randomx_cl.h b/src/backend/opencl/cl/rx/randomx_cl.h index 0fc7c6d2..4dc3bff2 100644 --- a/src/backend/opencl/cl/rx/randomx_cl.h +++ b/src/backend/opencl/cl/rx/randomx_cl.h @@ -2,7 +2,7 @@ namespace xmrig { -static const char randomx_cl[130953] = { +static const char randomx_cl[133218] = { 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x41,0x4c,0x47,0x4f,0x5f,0x43,0x4e,0x5f,0x30,0x20,0x30,0x78,0x36,0x33,0x31,0x35,0x30,0x30,0x30,0x30,0x0a,0x23,0x64,0x65, 0x66,0x69,0x6e,0x65,0x20,0x41,0x4c,0x47,0x4f,0x5f,0x43,0x4e,0x5f,0x31,0x20,0x30,0x78,0x36,0x33,0x31,0x35,0x30,0x31,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, 0x65,0x20,0x41,0x4c,0x47,0x4f,0x5f,0x43,0x4e,0x5f,0x32,0x20,0x30,0x78,0x36,0x33,0x31,0x35,0x30,0x32,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x41, @@ -1577,840 +1577,1098 @@ static const char randomx_cl[130953] = { 0x65,0x78,0x2a,0x38,0x3b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d, 0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x33,0x5d,0x3b,0x0a,0x74,0x5b, 0x34,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x34,0x5d,0x3b,0x0a,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35,0x5d,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x68, - 0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, - 0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x32,0x35,0x36,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x20,0x33,0x32,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f, - 0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x33,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f, - 0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68, - 0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x33,0x32,0x0a,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70, - 0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a, - 0x6f,0x75,0x74,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x6d,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e, - 0x67,0x2a,0x20,0x69,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x76,0x5b,0x31,0x36,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x69,0x76,0x30,0x5e,0x28,0x30,0x78, - 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69, - 0x76,0x34,0x20,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x69,0x76,0x30,0x20,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76, - 0x33,0x2c,0x69,0x76,0x34,0x5e,0x31,0x32,0x38,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32, - 0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x76,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30, - 0x5d,0x3d,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x5e,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74, - 0x5f,0x6c,0x65,0x6e,0x29,0x3b,0x0a,0x76,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x3d,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x5e,0x69,0x76,0x31,0x3b,0x0a, - 0x76,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x3d,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x5e,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x33,0x5d,0x3d,0x68, - 0x5b,0x33,0x5d,0x3d,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x5e,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x3d,0x76,0x5b, - 0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x5e,0x69,0x76,0x34,0x3b,0x0a,0x76,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x3d,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31, - 0x33,0x5d,0x5e,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x3d,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x5e,0x69,0x76,0x36, - 0x3b,0x0a,0x76,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x3d,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x5e,0x69,0x76,0x37,0x3b,0x0a,0x76,0x5b,0x38,0x5d, - 0x3d,0x69,0x76,0x30,0x3b,0x0a,0x76,0x5b,0x39,0x5d,0x3d,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x31,0x30,0x5d,0x3d,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x31,0x31,0x5d, - 0x3d,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x31,0x32,0x5d,0x3d,0x69,0x76,0x34,0x5e,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3b,0x0a,0x76,0x5b,0x31,0x33,0x5d,0x3d,0x69,0x76, - 0x35,0x3b,0x0a,0x76,0x5b,0x31,0x34,0x5d,0x3d,0x7e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x31,0x35,0x5d,0x3d,0x69,0x76,0x37,0x3b,0x0a,0x6d,0x5b,0x20,0x30,0x5d,0x3d, - 0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x32,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x31,0x5d,0x3d,0x28,0x69,0x6e, - 0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x33,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65, - 0x6e,0x3e,0x31,0x34,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31, - 0x35,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x30,0x29, - 0x3f,0x69,0x6e,0x5b,0x32,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x38,0x29,0x3f,0x69,0x6e, - 0x5b,0x32,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x36,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x37,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x32, - 0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x37,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x38,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x33,0x5d,0x3a,0x30, - 0x3b,0x0a,0x6d,0x5b,0x20,0x38,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x39,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x34,0x5d,0x3a,0x30,0x3b,0x0a,0x6d, - 0x5b,0x20,0x39,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x35,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x30, - 0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x31,0x5d,0x3d,0x28, - 0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x31,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f, - 0x6c,0x65,0x6e,0x3e,0x32,0x32,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e, - 0x3e,0x32,0x33,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34, - 0x30,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x38,0x29,0x3f, - 0x69,0x6e,0x5b,0x33,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f, - 0x6e,0x67,0x29,0x29,0x0a,0x6d,0x5b,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x2d,0x31,0x32,0x38,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67, - 0x29,0x5d,0x20,0x26,0x3d,0x20,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25, - 0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2a,0x38,0x29,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e, - 0x44,0x53,0x28,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x5e, - 0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x31,0x5d,0x3d, - 0x68,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x6f, - 0x75,0x74,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65, - 0x6e,0x3e,0x32,0x34,0x29,0x20,0x6f,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x3b,0x0a,0x69,0x66, - 0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x6f,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b, - 0x31,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x5e, - 0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x36, - 0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36, - 0x29,0x20,0x6f,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74, - 0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28, - 0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f, - 0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69, - 0x64,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x69,0x6e,0x2c,0x75, - 0x69,0x6e,0x74,0x20,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20, - 0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f, - 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x69,0x6e,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x2a,0x28,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x68,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f, - 0x6e,0x67,0x2a,0x29,0x20,0x6f,0x75,0x74,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x2f, - 0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6d,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x20,0x70,0x5b, - 0x30,0x5d,0x2c,0x70,0x5b,0x31,0x5d,0x2c,0x70,0x5b,0x32,0x5d,0x2c,0x70,0x5b,0x33,0x5d,0x2c,0x70,0x5b,0x34,0x5d,0x2c,0x70,0x5b,0x35,0x5d,0x2c,0x70,0x5b,0x36,0x5d, - 0x2c,0x70,0x5b,0x37,0x5d,0x2c,0x70,0x5b,0x38,0x5d,0x2c,0x70,0x5b,0x39,0x5d,0x2c,0x70,0x5b,0x31,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x31,0x5d,0x2c,0x70,0x5b,0x31,0x32, - 0x5d,0x2c,0x70,0x5b,0x31,0x33,0x5d,0x2c,0x70,0x5b,0x31,0x34,0x5d,0x2c,0x70,0x5b,0x31,0x35,0x5d,0x20,0x7d,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73, - 0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x68,0x61,0x73,0x68,0x2c,0x6d,0x2c,0x70,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65, - 0x6e,0x3e,0x30,0x29,0x20,0x68,0x5b,0x30,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29, - 0x20,0x68,0x5b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x68,0x5b, - 0x32,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x68,0x5b,0x33,0x5d,0x3d, - 0x68,0x61,0x73,0x68,0x5b,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x68,0x5b,0x34,0x5d,0x3d,0x68,0x61,0x73, - 0x68,0x5b,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x68,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35, - 0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x68,0x5b,0x36,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x68,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23, - 0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d, - 0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75, - 0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62, - 0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62, + 0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61, + 0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x76,0x61, + 0x72,0x69,0x61,0x62,0x6c,0x65,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x6d,0x2c,0x5f,0x5f,0x67,0x6c,0x6f, + 0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x69,0x6e,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x2c, + 0x75,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x76,0x5b,0x31,0x36,0x5d,0x20,0x3d,0x0a,0x7b,0x0a, + 0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76, + 0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x20,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x69,0x76,0x30,0x20,0x2c,0x69,0x76,0x31, + 0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x5e,0x31,0x32,0x38,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x7d,0x3b, + 0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x76, + 0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x3d,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x5e,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30, + 0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x3b,0x0a,0x76,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x3d,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39, + 0x5d,0x5e,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x3d,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x5e,0x69,0x76,0x32,0x3b, + 0x0a,0x76,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x3d,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x5e,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x34,0x5d,0x3d, + 0x68,0x5b,0x34,0x5d,0x3d,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x5e,0x69,0x76,0x34,0x3b,0x0a,0x76,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x3d,0x76, + 0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x5e,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x3d,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b, + 0x31,0x34,0x5d,0x5e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x3d,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x5e,0x69,0x76, + 0x37,0x3b,0x0a,0x76,0x5b,0x38,0x5d,0x3d,0x69,0x76,0x30,0x3b,0x0a,0x76,0x5b,0x39,0x5d,0x3d,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x31,0x30,0x5d,0x3d,0x69,0x76,0x32, + 0x3b,0x0a,0x76,0x5b,0x31,0x31,0x5d,0x3d,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x31,0x32,0x5d,0x3d,0x69,0x76,0x34,0x5e,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3b,0x0a,0x76, + 0x5b,0x31,0x33,0x5d,0x3d,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x31,0x34,0x5d,0x3d,0x7e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x31,0x35,0x5d,0x3d,0x69,0x76,0x37,0x3b, + 0x0a,0x6d,0x5b,0x20,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x32,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b, + 0x20,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x33,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x32,0x5d, + 0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x34,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x33,0x5d,0x3d,0x28,0x69, + 0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x35,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c, + 0x65,0x6e,0x3e,0x31,0x36,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e, + 0x31,0x36,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x36,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x37,0x36, + 0x29,0x3f,0x69,0x6e,0x5b,0x32,0x32,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x37,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x38,0x34,0x29,0x3f,0x69, + 0x6e,0x5b,0x32,0x33,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x38,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x39,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32, + 0x34,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x39,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x35,0x5d,0x3a, + 0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x36,0x5d,0x3a,0x30,0x3b,0x0a, + 0x6d,0x5b,0x31,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x31,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31, + 0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x32,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x33,0x5d,0x3d, + 0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x33,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x34,0x5d,0x3d,0x28,0x69,0x6e, + 0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65, + 0x6e,0x3e,0x32,0x34,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a, + 0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x0a,0x6d,0x5b,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x2d,0x31,0x32,0x38,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f, + 0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x5d,0x20,0x26,0x3d,0x20,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x28,0x69, + 0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2a,0x38,0x29,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45, + 0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x30, + 0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20, + 0x6f,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65, + 0x6e,0x3e,0x31,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x6f,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b, + 0x31,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x6f,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x5e, + 0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x35, + 0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38, + 0x29,0x20,0x6f,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74, + 0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x3b, + 0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75, + 0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62, + 0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x5f,0x68,0x61,0x73,0x68,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f, + 0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69, + 0x64,0x2a,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x54,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x54,0x65,0x6d,0x70,0x6c, + 0x61,0x74,0x65,0x53,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69, + 0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x70,0x3d,0x28,0x5f, + 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x54,0x65,0x6d,0x70,0x6c, + 0x61,0x74,0x65,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6d,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x20,0x70,0x5b,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x5d,0x2c,0x70,0x5b,0x32, + 0x5d,0x2c,0x70,0x5b,0x33,0x5d,0x2c,0x70,0x5b,0x34,0x5d,0x2c,0x70,0x5b,0x35,0x5d,0x2c,0x70,0x5b,0x36,0x5d,0x2c,0x70,0x5b,0x37,0x5d,0x2c,0x70,0x5b,0x38,0x5d,0x2c, + 0x70,0x5b,0x39,0x5d,0x2c,0x70,0x5b,0x31,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x31,0x5d,0x2c,0x70,0x5b,0x31,0x32,0x5d,0x2c,0x70,0x5b,0x31,0x33,0x5d,0x2c,0x70,0x5b,0x31, + 0x34,0x5d,0x2c,0x70,0x5b,0x31,0x35,0x5d,0x20,0x7d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x3d,0x73,0x74, + 0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x6d,0x5b,0x34,0x5d,0x3d,0x28,0x6d,0x5b, + 0x34,0x5d,0x26,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3e,0x3e,0x38,0x29,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3c,0x3c,0x35,0x36,0x29, + 0x3b,0x0a,0x6d,0x5b,0x35,0x5d,0x3d,0x28,0x6d,0x5b,0x35,0x5d,0x26,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3c,0x3c,0x32,0x34,0x29,0x29,0x7c, + 0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3e,0x3e,0x38,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x62,0x6c,0x61,0x6b,0x65, + 0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x76,0x61,0x72,0x69, + 0x61,0x62,0x6c,0x65,0x28,0x68,0x61,0x73,0x68,0x2c,0x6d,0x2c,0x70,0x2c,0x62,0x6c,0x6f,0x63,0x6b,0x54,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,0x53,0x69,0x7a,0x65,0x2c, + 0x36,0x34,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x6f,0x75,0x74,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x38,0x3b,0x0a,0x74, + 0x5b,0x30,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x3b,0x0a,0x74,0x5b,0x32,0x5d,0x3d, + 0x68,0x61,0x73,0x68,0x5b,0x32,0x5d,0x3b,0x0a,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x33,0x5d,0x3b,0x0a,0x74,0x5b,0x34,0x5d,0x3d,0x68,0x61,0x73,0x68, + 0x5b,0x34,0x5d,0x3b,0x0a,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35,0x5d,0x3b,0x0a,0x74,0x5b,0x36,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b, + 0x0a,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20, + 0x32,0x35,0x36,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x20,0x33,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62, 0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f, - 0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x73,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x36,0x34, - 0x0a,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x6d,0x2c, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x69,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e, - 0x67,0x20,0x76,0x5b,0x31,0x36,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74, - 0x5f,0x6c,0x65,0x6e,0x29,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x20,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69, - 0x76,0x37,0x2c,0x0a,0x69,0x76,0x30,0x20,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x5e,0x31,0x32,0x38,0x2c,0x69,0x76,0x35, - 0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x75, - 0x6c,0x6f,0x6e,0x67,0x20,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x76,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x3d,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x5e,0x69, - 0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x3b,0x0a,0x76,0x5b,0x31,0x5d,0x3d,0x68, - 0x5b,0x31,0x5d,0x3d,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x5e,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x3d,0x76,0x5b,0x32, - 0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x5e,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x3d,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31, - 0x5d,0x5e,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x3d,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x5e,0x69,0x76,0x34,0x3b, - 0x0a,0x76,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x3d,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x5e,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x36,0x5d,0x3d, - 0x68,0x5b,0x36,0x5d,0x3d,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x5e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x3d,0x76, - 0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x5e,0x69,0x76,0x37,0x3b,0x0a,0x76,0x5b,0x38,0x5d,0x3d,0x69,0x76,0x30,0x3b,0x0a,0x76,0x5b,0x39,0x5d,0x3d,0x69,0x76, - 0x31,0x3b,0x0a,0x76,0x5b,0x31,0x30,0x5d,0x3d,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x31,0x31,0x5d,0x3d,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x31,0x32,0x5d,0x3d,0x69, - 0x76,0x34,0x5e,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3b,0x0a,0x76,0x5b,0x31,0x33,0x5d,0x3d,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x31,0x34,0x5d,0x3d,0x7e,0x69,0x76,0x36, - 0x3b,0x0a,0x76,0x5b,0x31,0x35,0x5d,0x3d,0x69,0x76,0x37,0x3b,0x0a,0x6d,0x5b,0x20,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x32,0x38,0x29,0x3f, - 0x69,0x6e,0x5b,0x31,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x33,0x36,0x29,0x3f,0x69,0x6e,0x5b, - 0x31,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x34,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x38,0x5d, - 0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x35,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x39,0x5d,0x3a,0x30,0x3b, - 0x0a,0x6d,0x5b,0x20,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b, - 0x20,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x36,0x5d, - 0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x37,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x32,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x37,0x5d,0x3d,0x28,0x69, - 0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x38,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x33,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x38,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c, - 0x65,0x6e,0x3e,0x31,0x39,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x34,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x39,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e, - 0x32,0x30,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x35,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x38, - 0x29,0x3f,0x69,0x6e,0x5b,0x32,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x31,0x36,0x29,0x3f,0x69, - 0x6e,0x5b,0x32,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x32,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32, - 0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x33,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x39,0x5d,0x3a, - 0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x30,0x5d,0x3a,0x30,0x3b,0x0a, - 0x6d,0x5b,0x31,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28, - 0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x0a,0x6d,0x5b,0x28,0x69,0x6e,0x5f,0x6c,0x65, - 0x6e,0x2d,0x31,0x32,0x38,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x5d,0x20,0x26,0x3d,0x20,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29, - 0x28,0x2d,0x31,0x29,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67, - 0x29,0x29,0x2a,0x38,0x29,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f, - 0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x3b,0x0a,0x69,0x66, - 0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39, - 0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x5e,0x76,0x5b, - 0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x6f,0x75,0x74,0x5b,0x33,0x5d,0x3d, - 0x68,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20, - 0x6f,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c, - 0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x3b,0x0a,0x69, - 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x36,0x5d,0x5e,0x76, - 0x5b,0x31,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d, - 0x5e,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65, - 0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b, - 0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x73,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62, - 0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x69,0x6e,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42, - 0x79,0x74,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d, - 0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67, - 0x2a,0x29,0x20,0x69,0x6e,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74, - 0x65,0x73,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e, - 0x67,0x2a,0x20,0x68,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x6f,0x75,0x74,0x29,0x2b,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29, - 0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6d,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x20,0x70,0x5b,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x5d,0x2c,0x70,0x5b,0x32,0x5d,0x2c, - 0x70,0x5b,0x33,0x5d,0x2c,0x70,0x5b,0x34,0x5d,0x2c,0x70,0x5b,0x35,0x5d,0x2c,0x70,0x5b,0x36,0x5d,0x2c,0x70,0x5b,0x37,0x5d,0x2c,0x70,0x5b,0x38,0x5d,0x2c,0x70,0x5b, - 0x39,0x5d,0x2c,0x70,0x5b,0x31,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x31,0x5d,0x2c,0x70,0x5b,0x31,0x32,0x5d,0x2c,0x70,0x5b,0x31,0x33,0x5d,0x2c,0x70,0x5b,0x31,0x34,0x5d, - 0x2c,0x70,0x5b,0x31,0x35,0x5d,0x20,0x7d,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62, - 0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x68, - 0x61,0x73,0x68,0x2c,0x6d,0x2c,0x70,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x68,0x5b,0x30,0x5d,0x3d,0x68,0x61,0x73, - 0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x68,0x5b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d, - 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x68,0x5b,0x32,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x32,0x5d,0x3b,0x0a,0x69, - 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x68,0x5b,0x33,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x68,0x5b,0x34,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f, - 0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x68,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e, - 0x3e,0x34,0x38,0x29,0x20,0x68,0x5b,0x36,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36, - 0x29,0x20,0x68,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62, - 0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b, - 0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d, - 0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20, - 0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x36,0x34,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, - 0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41, - 0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x33,0x20,0x2d,0x20,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x29,0x0a,0x23,0x64,0x65,0x66,0x69, - 0x6e,0x65,0x20,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x45,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2d,0x20,0x31,0x29,0x20,0x26,0x20,0x7e,0x28,0x43,0x61,0x63,0x68,0x65, - 0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x20,0x2d,0x20,0x31,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53, - 0x69,0x7a,0x65,0x20,0x35,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x20,0x31,0x31,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x6d,0x61,0x6e, - 0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74, - 0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29, - 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x20,0x31,0x30,0x32,0x33,0x0a,0x23,0x64,0x65,0x66,0x69, - 0x6e,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x30,0x78,0x33,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69, - 0x6e,0x65,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65, - 0x20,0x73,0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x64,0x79, - 0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x28,0x6d,0x61,0x6e,0x74, - 0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x20,0x2b,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x29,0x29, - 0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x43,0x6f,0x75,0x6e,0x74,0x20,0x38,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x20,0x28,0x52,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x73,0x43,0x6f,0x75,0x6e,0x74,0x20,0x2f,0x20,0x32,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61, - 0x73,0x6b,0x20,0x28,0x28,0x31,0x20,0x3c,0x3c,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x42,0x49,0x54,0x53,0x29,0x20,0x2d,0x20,0x31, - 0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x74,0x6f,0x72,0x65,0x4c,0x33,0x43,0x6f,0x6e, - 0x64,0x69,0x74,0x69,0x6f,0x6e,0x20,0x31,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x61,0x74,0x61,0x73,0x65,0x74,0x45,0x78,0x74,0x72,0x61,0x49,0x74, - 0x65,0x6d,0x73,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x45,0x58,0x54,0x52,0x41,0x5f,0x53,0x49,0x5a,0x45,0x20, - 0x2f,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x49,0x54,0x45,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x23,0x64,0x65, - 0x66,0x69,0x6e,0x65,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4e,0x65,0x65,0x64,0x73,0x44,0x69,0x73,0x70,0x6c,0x61,0x63,0x65,0x6d,0x65,0x6e,0x74,0x20,0x35, - 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, - 0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x09,0x09,0x09,0x36,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x31,0x34,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x31,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53, - 0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x37,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x52, - 0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x45,0x47, - 0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x39,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x43,0x4f, - 0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x32,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x32,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d,0x5f,0x46,0x50,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x09,0x32,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x09,0x09,0x09,0x28,0x38,0x20,0x3c, - 0x3c,0x20,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75, - 0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b, - 0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20, - 0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x6c,0x6f,0x6e,0x67,0x20,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c, - 0x65,0x20,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x75,0x69,0x6e,0x74, - 0x36,0x34,0x5f,0x74,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e, - 0x74,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x3e,0x3e,0x35,0x39,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73, - 0x61,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x26,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74, - 0x2b,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x20,0x26,0x3d,0x20,0x65,0x78,0x70,0x6f, - 0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x20,0x3c,0x3c,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53, - 0x69,0x7a,0x65,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x7c,0x6d, - 0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x29,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x65,0x74,0x53,0x74,0x61,0x74,0x69,0x63,0x45,0x78, - 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36, - 0x34,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x3d,0x63,0x6f,0x6e,0x73,0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x3b,0x0a, - 0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x7c,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x74,0x61,0x74,0x69,0x63,0x45,0x78, - 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x29,0x29,0x3c,0x3c,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74, - 0x73,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x20,0x3c,0x3c,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x3b,0x0a,0x72,0x65, - 0x74,0x75,0x72,0x6e,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x65,0x74,0x46,0x6c,0x6f, - 0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x73,0x6b,0x32,0x32,0x62,0x69,0x74,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x32,0x32,0x29,0x2d,0x31,0x3b, - 0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x26,0x6d,0x61,0x73,0x6b,0x32,0x32,0x62,0x69,0x74,0x29,0x7c,0x67,0x65,0x74,0x53, - 0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x73, - 0x65,0x74,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x2a,0x64,0x73,0x74,0x5f, - 0x62,0x75,0x66,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61, - 0x6c,0x75,0x65,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30, - 0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x20,0x73,0x74,0x65,0x70,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66, - 0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x73,0x74, - 0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x64,0x73,0x74,0x5f,0x62,0x75,0x66,0x29,0x2b,0x69,0x3b,0x0a, - 0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x69,0x3c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x2a,0x4e,0x29,0x0a,0x7b,0x0a,0x2a, - 0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x64,0x73,0x74,0x29,0x3d,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a, - 0x64,0x73,0x74,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x69,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, - 0x20,0x69,0x6d,0x75,0x6c,0x5f,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x76,0x69,0x73,0x6f,0x72, - 0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x26,0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x2d,0x31,0x29,0x29,0x3d,0x3d,0x30,0x29, - 0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x31,0x55,0x4c,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20, - 0x70,0x32,0x65,0x78,0x70,0x36,0x33,0x3d,0x31,0x55,0x4c,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x71,0x75,0x6f,0x74,0x69,0x65, - 0x6e,0x74,0x3d,0x70,0x32,0x65,0x78,0x70,0x36,0x33,0x2f,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x6d, - 0x61,0x69,0x6e,0x64,0x65,0x72,0x3d,0x70,0x32,0x65,0x78,0x70,0x36,0x33,0x20,0x25,0x20,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x73,0x72,0x3d,0x33,0x31,0x2d,0x63,0x6c,0x7a,0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x29,0x3b,0x0a,0x66,0x6f, - 0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x30,0x3b,0x20,0x73,0x68,0x69,0x66,0x74,0x3c,0x3d,0x62,0x73,0x72,0x3b, - 0x20,0x2b,0x2b,0x73,0x68,0x69,0x66,0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x62,0x3d,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e, - 0x64,0x65,0x72,0x3e,0x3d,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x2d,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x29,0x3b,0x0a,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e, - 0x74,0x3d,0x28,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x62,0x3f,0x31,0x3a,0x30,0x29,0x3b,0x0a,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64, - 0x65,0x72,0x3d,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x3c,0x3c,0x31,0x29,0x2d,0x28,0x62,0x3f,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3a,0x30,0x29,0x3b, - 0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x73,0x65, - 0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x61,0x2c,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x64,0x6f,0x20,0x7b,0x20, - 0x28,0x28,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x26,0x28,0x61,0x29,0x29,0x5b,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x29,0x5d,0x20,0x3d,0x20,0x28, - 0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x20,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x30,0x29,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x65,0x74, - 0x5f,0x62,0x79,0x74,0x65,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x70,0x6f,0x73,0x69,0x74,0x69, - 0x6f,0x6e,0x29,0x20,0x7b,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x61,0x3e,0x3e,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3c,0x3c,0x33,0x29,0x29,0x26, - 0x30,0x78,0x46,0x46,0x3b,0x20,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65, - 0x2c,0x20,0x6e,0x65,0x78,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x64,0x6f,0x20,0x7b,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x3c, - 0x20,0x28,0x6e,0x65,0x78,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x3d,0x20,0x28,0x6e,0x65,0x78,0x74,0x5f,0x76, - 0x61,0x6c,0x75,0x65,0x29,0x3b,0x20,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x30,0x29,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f, - 0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29, - 0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6e,0x69,0x74,0x5f,0x76,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5f,0x64,0x61,0x74,0x61,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x2a,0x20,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e, - 0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20, - 0x32,0x35,0x36,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x3b,0x0a,0x23,0x65,0x6c,0x73, - 0x65,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69, - 0x66,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61, - 0x6e,0x5f,0x62,0x75,0x66,0x5b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52,0x4b,0x45, - 0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2a,0x28,0x33,0x32,0x2f,0x38,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63,0x5f,0x74, - 0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28, - 0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x2c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74, - 0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x2c,0x30, - 0x29,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74, - 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64, - 0x78,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2f,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x73,0x75,0x62,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x38,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65, - 0x78,0x65,0x63,0x5f,0x74,0x2a,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65, - 0x78,0x65,0x63,0x5f,0x74,0x2a,0x29,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x2b,0x28,0x67,0x65,0x74,0x5f, - 0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x38,0x29,0x2a,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53, - 0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63, - 0x5f,0x74,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20, - 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x52,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, - 0x29,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69, - 0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x52,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x3d,0x28,0x28,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5f,0x64,0x61, - 0x74,0x61,0x29,0x2b,0x69,0x64,0x78,0x2a,0x45,0x4e,0x54,0x52,0x4f,0x50,0x59,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74, - 0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x41,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x32,0x34,0x29,0x3b,0x0a,0x41,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d, - 0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x73,0x75,0x62, - 0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x75,0x62,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x30, - 0x29,0x0a,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, - 0x32,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x29, - 0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x2b,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a, + 0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f, + 0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x33,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x73,0x5f,0x33,0x32,0x0a,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f, + 0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x75,0x6c,0x6f, + 0x6e,0x67,0x2a,0x20,0x6d,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x69,0x6e,0x29,0x0a, + 0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x76,0x5b,0x31,0x36,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30, + 0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x20,0x2c,0x69,0x76,0x35, + 0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x69,0x76,0x30,0x20,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x5e,0x31, + 0x32,0x38,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44, + 0x53,0x28,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x76,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x3d,0x76,0x5b,0x30,0x5d,0x5e, + 0x76,0x5b,0x38,0x5d,0x5e,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x3b,0x0a, + 0x76,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x3d,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x5e,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x32,0x5d,0x3d,0x68,0x5b, + 0x32,0x5d,0x3d,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x5e,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x3d,0x76,0x5b,0x33, + 0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x5e,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x3d,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32, + 0x5d,0x5e,0x69,0x76,0x34,0x3b,0x0a,0x76,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x3d,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x5e,0x69,0x76,0x35,0x3b, + 0x0a,0x76,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x3d,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x5e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x37,0x5d,0x3d, + 0x68,0x5b,0x37,0x5d,0x3d,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x5e,0x69,0x76,0x37,0x3b,0x0a,0x76,0x5b,0x38,0x5d,0x3d,0x69,0x76,0x30,0x3b,0x0a,0x76, + 0x5b,0x39,0x5d,0x3d,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x31,0x30,0x5d,0x3d,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x31,0x31,0x5d,0x3d,0x69,0x76,0x33,0x3b,0x0a,0x76, + 0x5b,0x31,0x32,0x5d,0x3d,0x69,0x76,0x34,0x5e,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3b,0x0a,0x76,0x5b,0x31,0x33,0x5d,0x3d,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x31,0x34, + 0x5d,0x3d,0x7e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x31,0x35,0x5d,0x3d,0x69,0x76,0x37,0x3b,0x0a,0x6d,0x5b,0x20,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e, + 0x3e,0x31,0x32,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x33, + 0x36,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x34,0x34,0x29,0x3f, + 0x69,0x6e,0x5b,0x31,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x35,0x32,0x29,0x3f,0x69,0x6e,0x5b, + 0x31,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x30,0x5d, + 0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x31,0x5d,0x3a,0x30,0x3b, + 0x0a,0x6d,0x5b,0x20,0x36,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x37,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x32,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b, + 0x20,0x37,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x38,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x33,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x38,0x5d, + 0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x39,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x34,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x39,0x5d,0x3d,0x28,0x69, + 0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x35,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c, + 0x65,0x6e,0x3e,0x32,0x30,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x36,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e, + 0x32,0x31,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x37,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x32,0x34, + 0x29,0x3f,0x69,0x6e,0x5b,0x32,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x33,0x32,0x29,0x3f,0x69, + 0x6e,0x5b,0x32,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x34,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x33, + 0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x35,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x31,0x5d,0x3a, + 0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x0a,0x6d,0x5b, + 0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x2d,0x31,0x32,0x38,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x5d,0x20,0x26,0x3d,0x20,0x28, + 0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66, + 0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2a,0x38,0x29,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b, + 0x38,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x5e,0x76,0x5b, + 0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x68, + 0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x6f, + 0x75,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65, + 0x6e,0x3e,0x33,0x32,0x29,0x20,0x6f,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x6f,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b, + 0x31,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x5e, + 0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x37, + 0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65, + 0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29, + 0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x2a,0x6f,0x75,0x74,0x2c, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x69,0x6e,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x53, + 0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, + 0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x69,0x6e,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x69,0x6e,0x53,0x74,0x72, + 0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x68,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x6f,0x75, + 0x74,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28, + 0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6d,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x20,0x70,0x5b,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x5d, + 0x2c,0x70,0x5b,0x32,0x5d,0x2c,0x70,0x5b,0x33,0x5d,0x2c,0x70,0x5b,0x34,0x5d,0x2c,0x70,0x5b,0x35,0x5d,0x2c,0x70,0x5b,0x36,0x5d,0x2c,0x70,0x5b,0x37,0x5d,0x2c,0x70, + 0x5b,0x38,0x5d,0x2c,0x70,0x5b,0x39,0x5d,0x2c,0x70,0x5b,0x31,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x31,0x5d,0x2c,0x70,0x5b,0x31,0x32,0x5d,0x2c,0x70,0x5b,0x31,0x33,0x5d, + 0x2c,0x70,0x5b,0x31,0x34,0x5d,0x2c,0x70,0x5b,0x31,0x35,0x5d,0x20,0x7d,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x62, + 0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f, + 0x6e,0x61,0x6d,0x65,0x28,0x68,0x61,0x73,0x68,0x2c,0x6d,0x2c,0x70,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x68,0x5b, + 0x30,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x68,0x5b,0x31,0x5d,0x3d,0x68, + 0x61,0x73,0x68,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x68,0x5b,0x32,0x5d,0x3d,0x68,0x61,0x73,0x68, + 0x5b,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x68,0x5b,0x33,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x33,0x5d, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x68,0x5b,0x34,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x34,0x5d,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20,0x68,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x68,0x5b,0x36,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f, + 0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x68,0x5b,0x37,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62, + 0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65, + 0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f, + 0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6f, + 0x75,0x74,0x5f,0x6c,0x65,0x6e,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72, + 0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f, + 0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x36,0x34,0x0a,0x23,0x64,0x65,0x66, + 0x69,0x6e,0x65,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x20, + 0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x36,0x34,0x0a,0x76,0x6f,0x69,0x64,0x20,0x62, + 0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f, + 0x6e,0x61,0x6d,0x65,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x6d,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x69,0x6e,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x76,0x5b,0x31,0x36,0x5d, + 0x20,0x3d,0x0a,0x7b,0x0a,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x2c,0x69, + 0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x20,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76,0x37,0x2c,0x0a,0x69,0x76,0x30, + 0x20,0x2c,0x69,0x76,0x31,0x2c,0x69,0x76,0x32,0x2c,0x69,0x76,0x33,0x2c,0x69,0x76,0x34,0x5e,0x31,0x32,0x38,0x2c,0x69,0x76,0x35,0x2c,0x69,0x76,0x36,0x2c,0x69,0x76, + 0x37,0x2c,0x0a,0x7d,0x3b,0x0a,0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x5b, + 0x38,0x5d,0x3b,0x0a,0x76,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x3d,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x5e,0x69,0x76,0x30,0x5e,0x28,0x30,0x78,0x30, + 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x75,0x7c,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x29,0x3b,0x0a,0x76,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x3d,0x76,0x5b,0x31, + 0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x5e,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x3d,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30,0x5d, + 0x5e,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x3d,0x76,0x5b,0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x5e,0x69,0x76,0x33,0x3b,0x0a, + 0x76,0x5b,0x34,0x5d,0x3d,0x68,0x5b,0x34,0x5d,0x3d,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x5e,0x69,0x76,0x34,0x3b,0x0a,0x76,0x5b,0x35,0x5d,0x3d,0x68, + 0x5b,0x35,0x5d,0x3d,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x5e,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x3d,0x76,0x5b, + 0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x5e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x3d,0x76,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x31, + 0x35,0x5d,0x5e,0x69,0x76,0x37,0x3b,0x0a,0x76,0x5b,0x38,0x5d,0x3d,0x69,0x76,0x30,0x3b,0x0a,0x76,0x5b,0x39,0x5d,0x3d,0x69,0x76,0x31,0x3b,0x0a,0x76,0x5b,0x31,0x30, + 0x5d,0x3d,0x69,0x76,0x32,0x3b,0x0a,0x76,0x5b,0x31,0x31,0x5d,0x3d,0x69,0x76,0x33,0x3b,0x0a,0x76,0x5b,0x31,0x32,0x5d,0x3d,0x69,0x76,0x34,0x5e,0x69,0x6e,0x5f,0x6c, + 0x65,0x6e,0x3b,0x0a,0x76,0x5b,0x31,0x33,0x5d,0x3d,0x69,0x76,0x35,0x3b,0x0a,0x76,0x5b,0x31,0x34,0x5d,0x3d,0x7e,0x69,0x76,0x36,0x3b,0x0a,0x76,0x5b,0x31,0x35,0x5d, + 0x3d,0x69,0x76,0x37,0x3b,0x0a,0x6d,0x5b,0x20,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x32,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x36,0x5d,0x3a, + 0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x33,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x37,0x5d,0x3a,0x30,0x3b,0x0a, + 0x6d,0x5b,0x20,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x34,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20, + 0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x35,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x31,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x34,0x5d,0x3d, + 0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x35,0x5d,0x3d,0x28,0x69,0x6e, + 0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x36,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65, + 0x6e,0x3e,0x31,0x37,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x32,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x37,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31, + 0x38,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x33,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x38,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x39,0x32,0x29, + 0x3f,0x69,0x6e,0x5b,0x32,0x34,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x20,0x39,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x30,0x29,0x3f,0x69,0x6e, + 0x5b,0x32,0x35,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x30,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x30,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x36, + 0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x31,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x31,0x36,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x37,0x5d,0x3a,0x30, + 0x3b,0x0a,0x6d,0x5b,0x31,0x32,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x32,0x34,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x38,0x5d,0x3a,0x30,0x3b,0x0a,0x6d, + 0x5b,0x31,0x33,0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x33,0x32,0x29,0x3f,0x69,0x6e,0x5b,0x32,0x39,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x34, + 0x5d,0x3d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x30,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x30,0x5d,0x3a,0x30,0x3b,0x0a,0x6d,0x5b,0x31,0x35,0x5d,0x3d,0x28, + 0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x38,0x29,0x3f,0x69,0x6e,0x5b,0x33,0x31,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20, + 0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x0a,0x6d,0x5b,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x2d,0x31,0x32,0x38,0x29,0x2f, + 0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x5d,0x20,0x26,0x3d,0x20,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x2d,0x31,0x29,0x3e,0x3e,0x28, + 0x36,0x34,0x2d,0x28,0x69,0x6e,0x5f,0x6c,0x65,0x6e,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2a,0x38,0x29,0x3b,0x0a, + 0x42,0x4c,0x41,0x4b,0x45,0x32,0x42,0x5f,0x52,0x4f,0x55,0x4e,0x44,0x53,0x28,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20, + 0x6f,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x68,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x30,0x5d,0x5e,0x76,0x5b,0x38,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65, + 0x6e,0x3e,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x68,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x31,0x5d,0x5e,0x76,0x5b,0x39,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x68,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x32,0x5d,0x5e,0x76,0x5b,0x31,0x30, + 0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x6f,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x68,0x5b,0x33,0x5d,0x5e,0x76,0x5b, + 0x33,0x5d,0x5e,0x76,0x5b,0x31,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x33,0x32,0x29,0x20,0x6f,0x75,0x74,0x5b,0x34,0x5d,0x3d, + 0x68,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x34,0x5d,0x5e,0x76,0x5b,0x31,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29,0x20, + 0x6f,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x68,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x35,0x5d,0x5e,0x76,0x5b,0x31,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c, + 0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x6f,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x68,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x36,0x5d,0x5e,0x76,0x5b,0x31,0x34,0x5d,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x6f,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x68,0x5b,0x37,0x5d,0x5e,0x76,0x5b,0x37,0x5d,0x5e,0x76, + 0x5b,0x31,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b, + 0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76, + 0x6f,0x69,0x64,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x28, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x2a,0x6f,0x75,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x69,0x6e,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x29,0x0a,0x7b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f, + 0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a, + 0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x69,0x6e,0x29,0x2b, + 0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x69,0x6e,0x53,0x74,0x72,0x69,0x64,0x65,0x42,0x79,0x74,0x65,0x73,0x2f,0x73,0x69,0x7a,0x65, + 0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x68,0x3d,0x28,0x28, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x20,0x6f,0x75,0x74,0x29,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x2a,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x75,0x6c,0x6f,0x6e, + 0x67,0x20,0x6d,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x20,0x70,0x5b,0x30,0x5d,0x2c,0x70,0x5b,0x31,0x5d,0x2c,0x70,0x5b,0x32,0x5d,0x2c,0x70,0x5b,0x33,0x5d,0x2c,0x70,0x5b, + 0x34,0x5d,0x2c,0x70,0x5b,0x35,0x5d,0x2c,0x70,0x5b,0x36,0x5d,0x2c,0x70,0x5b,0x37,0x5d,0x2c,0x70,0x5b,0x38,0x5d,0x2c,0x70,0x5b,0x39,0x5d,0x2c,0x70,0x5b,0x31,0x30, + 0x5d,0x2c,0x70,0x5b,0x31,0x31,0x5d,0x2c,0x70,0x5b,0x31,0x32,0x5d,0x2c,0x70,0x5b,0x31,0x33,0x5d,0x2c,0x70,0x5b,0x31,0x34,0x5d,0x2c,0x70,0x5b,0x31,0x35,0x5d,0x20, + 0x7d,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73,0x68,0x5b,0x38,0x5d,0x3b,0x0a,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32,0x5f,0x70,0x72, + 0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x28,0x68,0x61,0x73,0x68,0x2c,0x6d,0x2c,0x70, + 0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x30,0x29,0x20,0x68,0x5b,0x30,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x38,0x29,0x20,0x68,0x5b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75, + 0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x31,0x36,0x29,0x20,0x68,0x5b,0x32,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x32,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c, + 0x65,0x6e,0x3e,0x32,0x34,0x29,0x20,0x68,0x5b,0x33,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x33,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e, + 0x33,0x32,0x29,0x20,0x68,0x5b,0x34,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x34,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x30,0x29, + 0x20,0x68,0x5b,0x35,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x35,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x34,0x38,0x29,0x20,0x68,0x5b, + 0x36,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x36,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x3e,0x35,0x36,0x29,0x20,0x68,0x5b,0x37,0x5d,0x3d, + 0x68,0x61,0x73,0x68,0x5b,0x37,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x68,0x61,0x73,0x68,0x5f,0x72, + 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x62,0x6c,0x61,0x6b,0x65,0x32,0x62,0x5f,0x35,0x31,0x32, + 0x5f,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x62,0x6c,0x6f,0x63,0x6b,0x5f,0x6e,0x61,0x6d,0x65,0x0a,0x23,0x75,0x6e,0x64,0x65, + 0x66,0x20,0x6f,0x75,0x74,0x5f,0x6c,0x65,0x6e,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49, + 0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x6b,0x68,0x72,0x5f,0x66,0x70,0x36,0x34,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68, + 0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f, + 0x4c,0x33,0x20,0x2d,0x20,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x61,0x63,0x68, + 0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54, + 0x5f,0x42,0x41,0x53,0x45,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2d,0x20,0x31,0x29,0x20,0x26,0x20,0x7e,0x28,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a, + 0x65,0x20,0x2d,0x20,0x31,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x20,0x35,0x32,0x0a, + 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x20,0x31,0x31,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69, + 0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28, + 0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, + 0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x20,0x31,0x30,0x32,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x63,0x6f,0x6e,0x73, + 0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x30,0x78,0x33,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x64,0x79,0x6e,0x61, + 0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x73,0x74,0x61,0x74,0x69,0x63, + 0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61, + 0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a, + 0x65,0x20,0x2b,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x29,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23, + 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x43,0x6f,0x75,0x6e,0x74,0x20,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x20,0x28,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x43,0x6f,0x75,0x6e,0x74, + 0x20,0x2f,0x20,0x32,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x20, + 0x3c,0x3c,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x42,0x49,0x54,0x53,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69, + 0x6e,0x65,0x20,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4f,0x66,0x66,0x73,0x65,0x74,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f, + 0x4f,0x46,0x46,0x53,0x45,0x54,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x74,0x6f,0x72,0x65,0x4c,0x33,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x20, + 0x31,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x61,0x74,0x61,0x73,0x65,0x74,0x45,0x78,0x74,0x72,0x61,0x49,0x74,0x65,0x6d,0x73,0x20,0x28,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x45,0x58,0x54,0x52,0x41,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2f,0x20,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x44,0x41,0x54,0x41,0x53,0x45,0x54,0x5f,0x49,0x54,0x45,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x4e,0x65,0x65,0x64,0x73,0x44,0x69,0x73,0x70,0x6c,0x61,0x63,0x65,0x6d,0x65,0x6e,0x74,0x20,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, + 0x65,0x20,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46, + 0x53,0x45,0x54,0x09,0x09,0x09,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x36,0x0a,0x23, + 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x09,0x31,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53, + 0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x09,0x31,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49, + 0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x37,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d, + 0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53, + 0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x31,0x39,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x09,0x09,0x32,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09, + 0x32,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d,0x5f,0x46,0x50,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x09,0x32, + 0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x09,0x09,0x09,0x28,0x38,0x20,0x3c,0x3c,0x20,0x4f,0x50,0x43,0x4f,0x44, + 0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b, + 0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65, + 0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75, + 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79, + 0x70,0x65,0x64,0x65,0x66,0x20,0x6c,0x6f,0x6e,0x67,0x20,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x67,0x65,0x74,0x53,0x6d, + 0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x6e, + 0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x3d,0x65,0x6e,0x74,0x72,0x6f, + 0x70,0x79,0x3e,0x3e,0x35,0x39,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x3d,0x65,0x6e,0x74,0x72,0x6f, + 0x70,0x79,0x26,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x2b,0x3d,0x65,0x78,0x70,0x6f,0x6e, + 0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x20,0x26,0x3d,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73, + 0x6b,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x20,0x3c,0x3c,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x3b,0x0a,0x72,0x65, + 0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x7c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61, + 0x29,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x65,0x74,0x53,0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28, + 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x78,0x70, + 0x6f,0x6e,0x65,0x6e,0x74,0x3d,0x63,0x6f,0x6e,0x73,0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e, + 0x74,0x7c,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42, + 0x69,0x74,0x73,0x29,0x29,0x3c,0x3c,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x3b,0x0a,0x65,0x78,0x70,0x6f, + 0x6e,0x65,0x6e,0x74,0x20,0x3c,0x3c,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x78, + 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28, + 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34, + 0x5f,0x74,0x20,0x6d,0x61,0x73,0x6b,0x32,0x32,0x62,0x69,0x74,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x32,0x32,0x29,0x2d,0x31,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e, + 0x20,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x26,0x6d,0x61,0x73,0x6b,0x32,0x32,0x62,0x69,0x74,0x29,0x7c,0x67,0x65,0x74,0x53,0x74,0x61,0x74,0x69,0x63,0x45,0x78, + 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x73,0x65,0x74,0x5f,0x62,0x75,0x66,0x66, + 0x65,0x72,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x2a,0x64,0x73,0x74,0x5f,0x62,0x75,0x66,0x2c,0x75,0x69,0x6e, + 0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x0a,0x7b,0x0a, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f, + 0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x65,0x70, + 0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x73,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f, + 0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x64,0x73,0x74,0x5f,0x62,0x75,0x66,0x29,0x2b,0x69,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28, + 0x69,0x3c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x2a,0x4e,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x64,0x73,0x74,0x29,0x3d,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x64,0x73,0x74,0x2b,0x3d,0x73,0x74, + 0x65,0x70,0x3b,0x0a,0x69,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6d,0x75,0x6c,0x5f,0x72, + 0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28, + 0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x26,0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x2d,0x31,0x29,0x29,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x31,0x55,0x4c,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x70,0x32,0x65,0x78,0x70,0x36,0x33, + 0x3d,0x31,0x55,0x4c,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e,0x74,0x3d,0x70,0x32,0x65,0x78, + 0x70,0x36,0x33,0x2f,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x3d, + 0x70,0x32,0x65,0x78,0x70,0x36,0x33,0x20,0x25,0x20,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x20,0x62,0x73,0x72,0x3d,0x33,0x31,0x2d,0x63,0x6c,0x7a,0x28,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x30,0x3b,0x20,0x73,0x68,0x69,0x66,0x74,0x3c,0x3d,0x62,0x73,0x72,0x3b,0x20,0x2b,0x2b,0x73,0x68,0x69,0x66, + 0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x62,0x3d,0x28,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x3e,0x3d,0x64,0x69, + 0x76,0x69,0x73,0x6f,0x72,0x2d,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x29,0x3b,0x0a,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e,0x74,0x3d,0x28,0x71,0x75,0x6f,0x74, + 0x69,0x65,0x6e,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x62,0x3f,0x31,0x3a,0x30,0x29,0x3b,0x0a,0x72,0x65,0x6d,0x61,0x69,0x6e,0x64,0x65,0x72,0x3d,0x28,0x72,0x65,0x6d, + 0x61,0x69,0x6e,0x64,0x65,0x72,0x3c,0x3c,0x31,0x29,0x2d,0x28,0x62,0x3f,0x64,0x69,0x76,0x69,0x73,0x6f,0x72,0x3a,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x71,0x75,0x6f,0x74,0x69,0x65,0x6e,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28, + 0x61,0x2c,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x64,0x6f,0x20,0x7b,0x20,0x28,0x28,0x75,0x69,0x6e,0x74,0x38, + 0x5f,0x74,0x2a,0x29,0x26,0x28,0x61,0x29,0x29,0x5b,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x29,0x5d,0x20,0x3d,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b, + 0x20,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x30,0x29,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x75, + 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x29,0x20,0x7b,0x20,0x72, + 0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x61,0x3e,0x3e,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3c,0x3c,0x33,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x3b,0x20,0x7d, + 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x20,0x6e,0x65,0x78,0x74,0x5f, + 0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x64,0x6f,0x20,0x7b,0x20,0x69,0x66,0x20,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x3c,0x20,0x28,0x6e,0x65,0x78,0x74,0x5f, + 0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x20,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x20,0x3d,0x20,0x28,0x6e,0x65,0x78,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x20, + 0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x30,0x29,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f, + 0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e, + 0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x69,0x6e,0x69,0x74,0x5f,0x76,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76, + 0x6f,0x69,0x64,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5f,0x64,0x61,0x74,0x61,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a, + 0x20,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x6f, + 0x75,0x6e,0x64,0x69,0x6e,0x67,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, + 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x74,0x79,0x70, + 0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x74,0x79,0x70,0x65,0x64, + 0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x5b,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f, + 0x48,0x41,0x53,0x48,0x2a,0x28,0x33,0x32,0x2f,0x38,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63,0x5f,0x74,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f, + 0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69, + 0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x2c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61, + 0x6e,0x5f,0x62,0x75,0x66,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x2c,0x30,0x29,0x3b,0x0a,0x62,0x61,0x72,0x72, + 0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, + 0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64,0x78,0x3d,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2f,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x3d,0x67,0x6c, + 0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x38,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x2a,0x20, + 0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x65,0x78,0x65,0x63,0x5f,0x74,0x2a,0x29, + 0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5f,0x62,0x75,0x66,0x2b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69, + 0x64,0x28,0x30,0x29,0x2f,0x38,0x29,0x2a,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52, + 0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x65,0x78,0x65,0x63,0x5f,0x74,0x29,0x2f,0x73,0x69,0x7a, + 0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f, + 0x74,0x2a,0x20,0x52,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x76,0x6d,0x5f,0x73,0x74,0x61, + 0x74,0x65,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69, + 0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x52,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x3d,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x67,0x6c, + 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5f,0x64,0x61,0x74,0x61,0x29,0x2b,0x69,0x64,0x78, + 0x2a,0x45,0x4e,0x54,0x52,0x4f,0x50,0x59,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x41,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75, + 0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x32,0x34,0x29,0x3b,0x0a,0x41,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69, + 0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x73,0x75,0x62,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28, + 0x73,0x75,0x62,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x6f,0x75,0x6e,0x64, + 0x69,0x6e,0x67,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x73,0x72,0x63,0x5f, + 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70, + 0x79,0x2b,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f, + 0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f, + 0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e, + 0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x38,0x5d,0x3d,0x7b,0x20,0x2d, + 0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66, + 0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52, + 0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x20,0x26,0x3d,0x20,0x7e,0x28,0x30,0x78,0x46, + 0x38,0x55,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63, + 0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74, + 0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x66,0x66,0x3b,0x0a,0x63, + 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29, + 0x26,0x37,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f, + 0x52,0x53,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53, + 0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a, 0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a, - 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a, - 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x23, - 0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, - 0x5b,0x38,0x5d,0x3d,0x7b,0x20,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x20,0x7d,0x3b, - 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x20,0x26, - 0x3d,0x20,0x7e,0x28,0x30,0x78,0x46,0x38,0x55,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x73,0x72,0x63,0x5f,0x69, - 0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73, - 0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26, - 0x30,0x78,0x66,0x66,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74, - 0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48, - 0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c, - 0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20, - 0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73, - 0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, - 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75, - 0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52, - 0x53,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x4d,0x55,0x4c,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d, - 0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a, - 0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65, - 0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74, - 0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b, - 0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d, - 0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x2b,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52, - 0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45, - 0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61, - 0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, - 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, - 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f, - 0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74, - 0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20, - 0x32,0x35,0x36,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, - 0x2c,0x64,0x73,0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, - 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x73,0x72,0x63,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x73,0x72,0x63,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e, - 0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53, - 0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53, - 0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f, - 0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29, - 0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x7c,0x3d,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, - 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50, - 0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51, - 0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52, - 0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x72,0x65,0x67,0x3d,0x64,0x73,0x74,0x3b, + 0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74, + 0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, + 0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, + 0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x2b,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42, + 0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x2b,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x2b,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74, + 0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f, + 0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72, + 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a, + 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64, + 0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f, + 0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b, 0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x29,0x3d,0x3d,0x30,0x29,0x3f,0x2d,0x31,0x3a,0x28,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x63,0x68,0x61,0x6e,0x67,0x65,0x29,0x3b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x63,0x72,0x65,0x67,0x7c,0x28,0x28,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x3d,0x3d,0x2d,0x31,0x29,0x3f,0x30,0x78,0x39,0x30,0x3a,0x30,0x78,0x31,0x30,0x29,0x29,0x3c,0x3c,0x38,0x29,0x7c,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x29,0x28,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x23,0x65, - 0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62, - 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x3d,0x28,0x73,0x72, - 0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x63,0x72,0x65,0x67,0x7c,0x30,0x78,0x31, - 0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2b,0x31,0x29,0x7c, - 0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49, - 0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x6d,0x70,0x3d,0x69,0x7c,0x28,0x69,0x3c,0x3c,0x38,0x29,0x3b, - 0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x74,0x6d,0x70,0x7c,0x28,0x74,0x6d,0x70,0x3c,0x3c,0x31, - 0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, - 0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x78,0x30,0x31,0x30,0x31, - 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x55,0x4c,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, - 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x30,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x5b,0x31,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x32,0x5d, - 0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x33,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x34,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x35,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x5b,0x36,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b, - 0x37,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74, - 0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65, - 0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65, - 0x6e,0x63,0x79,0x46,0x50,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79, - 0x63,0x6c,0x65,0x46,0x50,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68, - 0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x53,0x63,0x72, - 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, - 0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x5f, - 0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f, - 0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75,0x73,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x72, - 0x75,0x63,0x74,0x69,0x6f,0x6e,0x73,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63, - 0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63, - 0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63, - 0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d, - 0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x66,0x66,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, - 0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, - 0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32,0x34,0x29,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x62, - 0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21, - 0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x69,0x72,0x73,0x74, - 0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31, - 0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68, - 0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64, - 0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65, - 0x6e,0x63,0x79,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74, - 0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72, - 0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65, - 0x6e,0x63,0x79,0x3d,0x28,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3e,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3f,0x64,0x73, - 0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3a,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x65,0x6d,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x28,0x64,0x73,0x74,0x3d,0x3d,0x73,0x72, - 0x63,0x29,0x26,0x26,0x28,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x29, - 0x3e,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x32,0x29,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63, - 0x79,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x6d,0x65, - 0x6d,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x75,0x6c,0x6c,0x5f, - 0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f, - 0x72,0x79,0x5f,0x6f,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72, - 0x65,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c, - 0x20,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x3d,0x66, - 0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x6f,0x6f, - 0x6c,0x20,0x69,0x73,0x5f,0x66,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x66, - 0x61,0x6c,0x73,0x65,0x3b,0x0a,0x64,0x6f,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61, - 0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64, - 0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65, - 0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f, - 0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52, - 0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72, - 0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42, - 0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f, - 0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a, - 0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63, - 0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e, - 0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f, - 0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61, - 0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c, + 0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73, + 0x74,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65, + 0x64,0x2c,0x64,0x73,0x74,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, + 0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52, + 0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, + 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x73,0x65,0x74, + 0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x2c,0x69,0x29, + 0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73, + 0x74,0x2c,0x31,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, + 0x65,0x64,0x2c,0x73,0x72,0x63,0x2c,0x69,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43, + 0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x73,0x72,0x63,0x2c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, + 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a, + 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a, + 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x46,0x41,0x44,0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41, + 0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52, + 0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72, + 0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x7c,0x3d,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44, + 0x44,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52, + 0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x72,0x65,0x67,0x3d,0x64,0x73,0x74,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32,0x35,0x36,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, + 0x20,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57, + 0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2c,0x64,0x73,0x74,0x29,0x3d,0x3d,0x30,0x29,0x3f,0x2d,0x31,0x3a,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28, + 0x63,0x68,0x61,0x6e,0x67,0x65,0x29,0x3b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73, + 0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x46,0x46,0x30,0x30, + 0x30,0x30,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x63,0x72,0x65,0x67,0x7c,0x28,0x28,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x3d,0x2d,0x31,0x29, + 0x3f,0x30,0x78,0x39,0x30,0x3a,0x30,0x78,0x31,0x30,0x29,0x29,0x3c,0x3c,0x38,0x29,0x7c,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x6c,0x61, + 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, + 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x63,0x72,0x65,0x67,0x7c,0x30,0x78,0x31,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b, + 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72, + 0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x6c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x2b,0x31,0x29,0x7c,0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c, + 0x38,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3c,0x3d,0x20,0x32, + 0x35,0x36,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x6d,0x70,0x3d,0x69,0x7c,0x28,0x69,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x74,0x6d,0x70,0x7c,0x28,0x74,0x6d,0x70,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67, + 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a, + 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x78,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30, + 0x31,0x30,0x31,0x30,0x31,0x55,0x4c,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, + 0x65,0x64,0x5b,0x30,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x31,0x5d,0x3d, + 0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x32,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67, + 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x33,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, + 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x34,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x5b,0x35,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x36, + 0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x37,0x5d,0x3d,0x69,0x3b,0x0a,0x23, + 0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65, + 0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x3d,0x30, + 0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x3d,0x30, + 0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79, + 0x3d,0x30,0x3b,0x0a,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64, + 0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62, + 0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64, + 0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73, + 0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f, + 0x6f,0x70,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75, + 0x73,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x73, + 0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c, + 0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70, + 0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65, + 0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62, + 0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a, + 0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f, + 0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e, + 0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x66,0x66,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e, + 0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x28, + 0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x6f, + 0x64,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32,0x34,0x29,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74, + 0x61,0x72,0x67,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28, + 0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61, + 0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x66,0x69,0x72,0x73,0x74, + 0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74, + 0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65, + 0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x64,0x73,0x74, + 0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65, + 0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x64,0x73, + 0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3e,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3f,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3a,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d, + 0x65,0x6d,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x28,0x64,0x73,0x74,0x3d,0x3d,0x73,0x72,0x63,0x29,0x26,0x26,0x28,0x28,0x69, + 0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x29,0x3e,0x3d,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x32,0x29,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67, + 0x68,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x6d,0x65,0x6d,0x5f,0x72,0x65,0x61,0x64,0x5f, + 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61, + 0x74,0x65,0x6e,0x63,0x79,0x2c,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x20,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x30,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x66, + 0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x66,0x61,0x6c,0x73,0x65, + 0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x62,0x72,0x61, + 0x6e,0x63,0x68,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62, + 0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x66,0x70, + 0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x64, + 0x6f,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f, + 0x52,0x53,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a, + 0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41, + 0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41, + 0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63, + 0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74, + 0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61, + 0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f, + 0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72, + 0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c, 0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65, 0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74, - 0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65, - 0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62, + 0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, + 0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c, + 0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b, + 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f, + 0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62, 0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d, - 0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d, - 0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x69,0x66,0x28, - 0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73,0x74,0x5f,0x6c, - 0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b, - 0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50, - 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x29, - 0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73, - 0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65, - 0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f, - 0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b, - 0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52, - 0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65, - 0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a, - 0x69,0x66,0x28,0x64,0x73,0x74,0x21,0x3d,0x73,0x72,0x63,0x29,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61, - 0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a, - 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a, - 0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e, - 0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65, - 0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a, - 0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d, - 0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62, - 0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61, - 0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x70,0x64, - 0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63, - 0x79,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75, + 0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53, + 0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65, + 0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d, + 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a, + 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29, + 0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26, + 0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b, + 0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73, + 0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65, + 0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x66,0x75,0x6c,0x6c,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61, + 0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b, + 0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a, + 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67, + 0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x66,0x28,0x64,0x73,0x74,0x21, + 0x3d,0x73,0x72,0x63,0x29,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a, + 0x65,0x6c,0x73,0x65,0x0a,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73, + 0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73, 0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c, - 0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65, - 0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72, - 0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c, - 0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28, - 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66, - 0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29, + 0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46, + 0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74, + 0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f, + 0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67, + 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28, + 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78, + 0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x73,0x5f, + 0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61, + 0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29, 0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65, 0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64, 0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c, 0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43, - 0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e, - 0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73, - 0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73, - 0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75, + 0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20,0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46, + 0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74, + 0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c, + 0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79, + 0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b, + 0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x20, + 0x25,0x3d,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74, + 0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73, + 0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65, + 0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c, + 0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f, + 0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74, + 0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f, + 0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f, + 0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61, + 0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29, + 0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b, + 0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79, + 0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74, + 0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61, + 0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79, + 0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65, + 0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46, + 0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75, 0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79, 0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x29, - 0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79, - 0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64, - 0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f, - 0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x3b,0x0a, - 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79, - 0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64, - 0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c, - 0x73,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73,0x74,0x5f, - 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6c,0x61, - 0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, - 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79, - 0x3d,0x73,0x72,0x63,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62, - 0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52, - 0x4f,0x55,0x4e,0x44,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54, - 0x4f,0x52,0x45,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b, - 0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x28,0x6c,0x61,0x73,0x74,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79, - 0x5f,0x6f,0x70,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2f,0x57,0x4f,0x52,0x4b,0x45, - 0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b, - 0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x3b,0x0a,0x69,0x73,0x5f, - 0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x66,0x61,0x6c,0x73,0x65,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73, - 0x5f,0x6e,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75, - 0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d, - 0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61, - 0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x2a,0x29,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x7c,0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x75,0x70,0x64,0x61, - 0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x69,0x73,0x5f, - 0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69, - 0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65, - 0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f, - 0x73,0x6c,0x6f,0x74,0x2c,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a, - 0x69,0x66,0x28,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f, - 0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x69,0x73,0x5f,0x66,0x70,0x3f,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x3a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c, - 0x65,0x2c,0x64,0x73,0x74,0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f, - 0x73,0x77,0x61,0x70,0x29,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73, - 0x6c,0x6f,0x74,0x2c,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x73, - 0x72,0x63,0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73, - 0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x75,0x70,0x64, - 0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2c,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65, - 0x64,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29,0x0a,0x7b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65, - 0x3d,0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65, - 0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x20,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3c,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x69,0x66, - 0x28,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x65,0x78,0x65,0x63,0x75,0x74, - 0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x2b,0x31,0x5d,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x28,0x6a,0x2b,0x31,0x29,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b, - 0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x29,0x0a,0x7b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x65,0x64,0x3d,0x66,0x61, - 0x6c,0x73,0x65,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x6a,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50, - 0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x20,0x6b,0x3c,0x6a,0x3b,0x20, - 0x2b,0x2b,0x6b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x7c,0x7c,0x28,0x6b,0x3d, - 0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73, - 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63, - 0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x5d,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x32, - 0x30,0x3c,0x3c,0x38,0x29,0x29,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x35,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d, - 0x30,0x29,0x7c,0x7c,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x62,0x6c,0x6f,0x63,0x6b,0x65,0x64, - 0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x21,0x62,0x6c,0x6f,0x63,0x6b, - 0x65,0x64,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x6a,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f, - 0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x20,0x6b,0x3c,0x6a,0x3b, - 0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x7c,0x7c,0x28,0x6b, - 0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65, - 0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x5d,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x32, - 0x30,0x3c,0x3c,0x38,0x29,0x29,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x65, - 0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x3b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e, - 0x5b,0x6a,0x2b,0x31,0x5d,0x3d,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x66,0x69, - 0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x6b,0x29,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69, - 0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6a,0x3b,0x0a,0x69,0x66,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74, - 0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x6b,0x2b,0x31,0x29,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63, - 0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6a,0x2b,0x31,0x3b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x6b,0x3b,0x0a,0x62,0x72, - 0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3c,0x30,0x29,0x0a,0x7b,0x0a,0x73, - 0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x6a,0x3b,0x0a,0x7d,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x65, - 0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77, - 0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x20,0x6a,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x20,0x2b,0x2b,0x6a,0x29, - 0x0a,0x7b,0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x73,0x6c, - 0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x6a,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x3d,0x3d, - 0x30,0x29,0x0a,0x7b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x73,0x6c,0x6f,0x74, - 0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x3d,0x69,0x73, - 0x5f,0x66,0x70,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x0a,0x7b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c, - 0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2d,0x28, - 0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b, - 0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x0a,0x7d,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75, - 0x63,0x74,0x69,0x6f,0x6e,0x73,0x3b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75, - 0x73,0x65,0x5d,0x3d,0x69,0x3b,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75,0x73,0x65,0x64,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66, - 0x70,0x29,0x0a,0x7b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b, - 0x31,0x5d,0x3d,0x69,0x3b,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75,0x73,0x65,0x64,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75, - 0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x73,0x72, - 0x63,0x5f,0x72,0x65,0x61,0x64,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65, - 0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x73,0x72,0x63,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f, - 0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45, - 0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79, - 0x63,0x6c,0x65,0x2c,0x73,0x72,0x63,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f, - 0x70,0x29,0x0a,0x7b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x73,0x74,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x5f,0x73, - 0x6c,0x6f,0x74,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e, - 0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e, - 0x63,0x79,0x7c,0x28,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, - 0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x3d,0x74,0x7c,0x28,0x74,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e, - 0x63,0x79,0x46,0x50,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29, - 0x0a,0x7b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73, - 0x74,0x2c,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67, - 0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x2c,0x64,0x73,0x74,0x29, - 0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57, - 0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x2c,0x64,0x73,0x74,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73, - 0x65,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x21,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x26,0x26,0x21,0x69,0x73,0x5f,0x6e,0x6f,0x70, - 0x29,0x0a,0x7b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x64,0x73,0x74, - 0x2c,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x29,0x0a,0x73,0x65,0x74,0x5f, - 0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x2c,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61, - 0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61, - 0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f, - 0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c, - 0x65,0x2c,0x64,0x73,0x74,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x29,0x0a,0x7b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x7c,0x28,0x6e, - 0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79, - 0x3d,0x74,0x7c,0x28,0x74,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3c,0x3c,0x33,0x32, - 0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79, - 0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f, - 0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79, - 0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b, - 0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f, - 0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29, - 0x3e,0x3d,0x53,0x74,0x6f,0x72,0x65,0x4c,0x33,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69, - 0x67,0x68,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50, - 0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61, - 0x6e,0x5b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5d,0x7c,0x7c,0x28,0x66,0x69,0x72,0x73,0x74,0x5f, - 0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f, - 0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c, - 0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72, - 0x61,0x6d,0x5b,0x69,0x5d,0x2e,0x78,0x7c,0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x7d, - 0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29,0x0a,0x2b,0x2b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f, - 0x74,0x3b,0x0a,0x64,0x6f,0x20,0x7b,0x0a,0x2b,0x2b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a, - 0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3c,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f, - 0x48,0x41,0x53,0x48,0x29,0x26,0x26,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5d,0x21,0x3d,0x30,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63, - 0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x69,0x73,0x5f,0x66,0x70,0x3f,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x32, - 0x29,0x3a,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x31,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78, - 0x28,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x69,0x73,0x5f,0x66,0x70,0x3f,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75, - 0x73,0x65,0x2b,0x31,0x29,0x3a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x29,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x65,0x78,0x65,0x63,0x75, - 0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5d,0x7c,0x7c,0x28,0x6c,0x61,0x73,0x74, - 0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c, - 0x6f,0x74,0x29,0x7c,0x7c,0x28,0x28,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73, - 0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74, - 0x69,0x6f,0x6e,0x5f,0x66,0x70,0x29,0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x7d,0x0a,0x2d, - 0x2d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x26,0x26,0x28,0x6c,0x61,0x73,0x74, - 0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3e,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63, - 0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x29,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f, - 0x75,0x6e,0x64,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6d,0x61,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x38,0x5d,0x29,0x26,0x43,0x61,0x63,0x68,0x65, - 0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x78,0x3d,0x28,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x30,0x5d,0x29,0x26,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67, - 0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73, - 0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73, - 0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3d,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29, - 0x7c,0x28,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x32,0x29,0x3f,0x33,0x55,0x3a,0x32,0x55,0x29,0x3c,0x3c, - 0x38,0x29,0x7c,0x28,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x34,0x29,0x3f,0x35,0x55,0x3a,0x34,0x55,0x29, - 0x3c,0x3c,0x31,0x36,0x29,0x7c,0x28,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x38,0x29,0x3f,0x37,0x55,0x3a, - 0x36,0x55,0x29,0x3c,0x3c,0x32,0x34,0x29,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x33,0x5d,0x26, - 0x44,0x61,0x74,0x61,0x73,0x65,0x74,0x45,0x78,0x74,0x72,0x61,0x49,0x74,0x65,0x6d,0x73,0x29,0x2a,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65, - 0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x32,0x20,0x65,0x4d,0x61,0x73,0x6b,0x3d,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x32, - 0x2a,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x2b,0x31,0x34,0x29,0x3b,0x0a,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x78,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74, - 0x4d,0x61,0x73,0x6b,0x28,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x78,0x29,0x3b,0x0a,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x79,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d, - 0x61,0x73,0x6b,0x28,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x79,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, - 0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x6d,0x78,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x32,0x5d,0x3d,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67, - 0x69,0x73,0x74,0x65,0x72,0x73,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b, - 0x31,0x36,0x29,0x29,0x5b,0x33,0x5d,0x3d,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x32,0x2a,0x29,0x28,0x52,0x2b,0x31,0x38,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x65,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x5f,0x5f,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a, - 0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64, - 0x65,0x78,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3d, - 0x2d,0x31,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f, - 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x28, - 0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53,0x49,0x5a,0x45,0x29,0x2f,0x73,0x69,0x7a, - 0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74, - 0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72, - 0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74, - 0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x21,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x5d,0x7c, - 0x7c,0x28,0x69,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x7c,0x7c,0x28,0x28, - 0x69,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69, - 0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x29,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3d,0x30,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77, - 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x26,0x26,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d, - 0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x29,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x26,0x26,0x28, - 0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5d,0x7c,0x7c,0x28, - 0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e, - 0x5f,0x73,0x6c,0x6f,0x74,0x29,0x7c,0x7c,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69, - 0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75, - 0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x29,0x29,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x28,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x26,0x31,0x29, - 0x26,0x26,0x28,0x28,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69, - 0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5d,0x5d,0x2e,0x78,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x29,0x29, - 0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a, - 0x7d,0x0a,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x28,0x28,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x2d,0x31,0x29,0x3c,0x3c, - 0x4e,0x55,0x4d,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3c, - 0x3c,0x4e,0x55,0x4d,0x5f,0x46,0x50,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e, - 0x74,0x32,0x20,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f, - 0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x5d,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x3b, - 0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x66,0x66,0x3b,0x0a,0x63,0x6f, - 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26, - 0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32, - 0x34,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x66,0x70,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x26,0x26,0x28,0x28,0x69,0x26,0x31,0x29, - 0x3d,0x3d,0x30,0x29,0x29,0x0a,0x2b,0x2b,0x69,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f, - 0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30, - 0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x26,0x26,0x28,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74, - 0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f,0x74,0x3c,0x30,0x29,0x29,0x0a,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f, - 0x74,0x3d,0x6b,0x3b,0x0a,0x2b,0x2b,0x6b,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x32,0x29,0x20,0x25,0x20,0x34,0x3b,0x0a, - 0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53, - 0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, - 0x3b,0x0a,0x69,0x66,0x28,0x64,0x73,0x74,0x21,0x3d,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4e,0x65,0x65,0x64,0x73,0x44,0x69,0x73,0x70,0x6c,0x61,0x63,0x65,0x6d, - 0x65,0x6e,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, - 0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49, - 0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45, - 0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e, - 0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e, - 0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f, - 0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c, - 0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31, - 0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, - 0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b, - 0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69, - 0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43, - 0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a, - 0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c, - 0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d, + 0x3b,0x0a,0x69,0x73,0x5f,0x66,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b, + 0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46, + 0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43, + 0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x69,0x73,0x5f, + 0x62,0x72,0x61,0x6e,0x63,0x68,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x64,0x73,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79, + 0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64, + 0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x73,0x72,0x63,0x5f,0x6c,0x61, + 0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d, + 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x29,0x0a,0x7b,0x0a, + 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x5f,0x72,0x65,0x61,0x64,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65, + 0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x28,0x6c,0x61,0x73,0x74,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x5f,0x73,0x6c,0x6f, + 0x74,0x2b,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f, + 0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x6d,0x65,0x6d, + 0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, + 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x3b,0x0a,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x3d,0x74,0x72,0x75, + 0x65,0x3b,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x66,0x61,0x6c,0x73,0x65,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x29,0x0a,0x7b, + 0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62, + 0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, + 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61, + 0x72,0x6b,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x5f, + 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x69,0x29,0x7c,0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x62,0x72,0x61,0x6e, + 0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x6d,0x61,0x72,0x6b,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f, + 0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c, + 0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a, + 0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x6c,0x61, + 0x74,0x65,0x6e,0x63,0x79,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x63, + 0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64, + 0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64, + 0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64, + 0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x69,0x73,0x5f,0x66,0x70,0x3f,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61, + 0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x3a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x29,0x2a, + 0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x29,0x0a,0x75, + 0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x67,0x65,0x74, + 0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x73,0x72,0x63,0x29,0x2a,0x57,0x4f,0x52, + 0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f, + 0x75,0x73,0x65,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78, + 0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2c,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x29, + 0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29,0x0a,0x7b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x2d,0x31,0x3b,0x0a,0x66,0x6f, + 0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b, + 0x20,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3c,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x28,0x65,0x78,0x65,0x63,0x75, + 0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61, + 0x6e,0x5b,0x6a,0x2b,0x31,0x5d,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x28,0x6a,0x2b,0x31,0x29,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52, + 0x5f,0x48,0x41,0x53,0x48,0x29,0x29,0x0a,0x7b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x65,0x64,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x66,0x6f, + 0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x6a,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48, + 0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x20,0x6b,0x3c,0x6a,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x7b,0x0a, + 0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x7c,0x7c,0x28,0x6b,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f, + 0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70, + 0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x5d,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x3d, + 0x3d,0x30,0x29,0x26,0x26,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x35,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x29,0x7c,0x7c,0x69,0x73,0x5f, + 0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x62,0x6c,0x6f,0x63,0x6b,0x65,0x64,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a, + 0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x21,0x62,0x6c,0x6f,0x63,0x6b,0x65,0x64,0x29,0x0a,0x7b,0x0a,0x66, + 0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x6a,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53, + 0x48,0x29,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x20,0x6b,0x3c,0x6a,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x7b, + 0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x7c,0x7c,0x28,0x6b,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74, + 0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f, + 0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x5d,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x3d, + 0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f, + 0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x5d,0x3b,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x2b,0x31,0x5d,0x3d,0x65, + 0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6b,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73, + 0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x6b,0x29,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74, + 0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6a,0x3b,0x0a,0x69,0x66,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e, + 0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x6b,0x2b,0x31,0x29,0x20,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c, + 0x6f,0x74,0x3d,0x6a,0x2b,0x31,0x3b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3d,0x6b,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a, + 0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x3c,0x30,0x29,0x0a,0x7b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f, + 0x75,0x73,0x65,0x3d,0x6a,0x3b,0x0a,0x7d,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x66, + 0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74, + 0x3b,0x20,0x6a,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x65, + 0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x6a,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75, + 0x73,0x65,0x3d,0x6a,0x3b,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x66,0x69, + 0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65, + 0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x3d,0x69,0x73,0x5f,0x66,0x70,0x3b,0x0a,0x7d,0x0a, + 0x69,0x66,0x28,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x0a,0x7b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73, + 0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f, + 0x5f,0x75,0x73,0x65,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53, + 0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3b,0x0a,0x7d,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x73,0x3b, + 0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x5d,0x3d,0x69,0x3b,0x0a, + 0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75,0x73,0x65,0x64,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29,0x0a,0x7b,0x0a,0x65,0x78, + 0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x31,0x5d,0x3d,0x69,0x3b,0x0a,0x2b, + 0x2b,0x6e,0x75,0x6d,0x5f,0x73,0x6c,0x6f,0x74,0x73,0x5f,0x75,0x73,0x65,0x64,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x20,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b, + 0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x73,0x72,0x63,0x5f,0x72,0x65,0x61,0x64,0x29, + 0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x73,0x72,0x63,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c, + 0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29, + 0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x73,0x72,0x63, + 0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x75,0x70, + 0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x73,0x74,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x6f,0x70,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x73,0x6c,0x6f, + 0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29,0x0a,0x7b,0x0a,0x63,0x6f, + 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x7c,0x28,0x6e,0x65,0x78, + 0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50, + 0x3d,0x74,0x7c,0x28,0x74,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x3d,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79, + 0x46,0x50,0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x29,0x0a,0x7b,0x0a,0x73,0x65,0x74,0x5f, + 0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x46,0x50,0x2c,0x64,0x73,0x74,0x2c,0x6e,0x65,0x78,0x74,0x5f, + 0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65, + 0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74, + 0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f, + 0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64, + 0x43,0x79,0x63,0x6c,0x65,0x46,0x50,0x2c,0x64,0x73,0x74,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x69,0x66,0x28, + 0x21,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x26,0x26,0x21,0x69,0x73,0x5f,0x6e,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x73,0x65,0x74, + 0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x64,0x73,0x74,0x2c,0x6e,0x65,0x78,0x74,0x5f,0x6c, + 0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x73,0x77,0x61,0x70,0x29,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x2c,0x73,0x72,0x63,0x2c,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x29,0x3b, + 0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65, + 0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a, + 0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x2c,0x76, + 0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, + 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74,0x65,0x6e,0x63,0x79,0x7c,0x28,0x6e,0x65,0x78,0x74,0x5f,0x6c,0x61,0x74, + 0x65,0x6e,0x63,0x79,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x74,0x7c,0x28,0x74,0x3c,0x3c, + 0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74, + 0x65,0x6e,0x63,0x79,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66, + 0x28,0x69,0x73,0x5f,0x6d,0x65,0x6d,0x6f,0x72,0x79,0x5f,0x73,0x74,0x6f,0x72,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75, + 0x65,0x3d,0x67,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74, + 0x29,0x3b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x76,0x61,0x6c,0x75,0x65,0x2c,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f, + 0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x3b,0x0a,0x73,0x65,0x74,0x5f,0x62,0x79,0x74,0x65,0x28,0x72,0x65,0x67,0x69, + 0x73,0x74,0x65,0x72,0x52,0x65,0x61,0x64,0x43,0x79,0x63,0x6c,0x65,0x2c,0x64,0x73,0x74,0x2c,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x53,0x63,0x72,0x61,0x74,0x63, + 0x68,0x70,0x61,0x64,0x4c,0x61,0x74,0x65,0x6e,0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53, + 0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3e,0x3d,0x53,0x74,0x6f,0x72,0x65, + 0x4c,0x33,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x4c,0x61,0x74,0x65,0x6e, + 0x63,0x79,0x3d,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2f,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48, + 0x29,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x66,0x69,0x72,0x73,0x74, + 0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5d,0x7c,0x7c,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62, + 0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29, + 0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x69,0x73,0x5f,0x62, + 0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x5d,0x2e,0x78, + 0x7c,0x3d,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x3b,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x5f, + 0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f, + 0x66,0x70,0x29,0x0a,0x2b,0x2b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x64,0x6f,0x20,0x7b, + 0x0a,0x2b,0x2b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65, + 0x20,0x28,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f,0x73,0x6c,0x6f,0x74,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x26,0x26, + 0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f, + 0x73,0x6c,0x6f,0x74,0x5d,0x21,0x3d,0x30,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65, + 0x74,0x29,0x0a,0x7b,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5f, + 0x73,0x6c,0x6f,0x74,0x2c,0x69,0x73,0x5f,0x66,0x70,0x3f,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x32,0x29,0x3a,0x28,0x73,0x6c,0x6f,0x74, + 0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x31,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x75,0x70,0x64,0x61,0x74,0x65,0x5f,0x6d,0x61,0x78,0x28,0x6c,0x61,0x73,0x74,0x5f,0x75, + 0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2c,0x69,0x73,0x5f,0x66,0x70,0x3f,0x28,0x73,0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x2b,0x31,0x29,0x3a,0x73, + 0x6c,0x6f,0x74,0x5f,0x74,0x6f,0x5f,0x75,0x73,0x65,0x29,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c, + 0x61,0x6e,0x5b,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5d,0x7c,0x7c,0x28,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73, + 0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x7c,0x7c,0x28,0x28, + 0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f, + 0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x29, + 0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x7d,0x0a,0x2d,0x2d,0x6c,0x61,0x73,0x74,0x5f,0x75, + 0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x26,0x26,0x28,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73, + 0x6c,0x6f,0x74,0x3e,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x29, + 0x29,0x0a,0x66,0x69,0x72,0x73,0x74,0x5f,0x61,0x6c,0x6c,0x6f,0x77,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x5f,0x63,0x66,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x6c,0x61,0x73, + 0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x61,0x3d,0x28,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x38,0x5d,0x29,0x26,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69, + 0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x78,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65, + 0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x30,0x5d,0x29,0x26,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x32,0x5d,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x73,0x3d,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x7c,0x28,0x28,0x28,0x61,0x64,0x64, + 0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x32,0x29,0x3f,0x33,0x55,0x3a,0x32,0x55,0x29,0x3c,0x3c,0x38,0x29,0x7c,0x28,0x28,0x28,0x61, + 0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x34,0x29,0x3f,0x35,0x55,0x3a,0x34,0x55,0x29,0x3c,0x3c,0x31,0x36,0x29,0x7c,0x28, + 0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x38,0x29,0x3f,0x37,0x55,0x3a,0x36,0x55,0x29,0x3c,0x3c,0x32,0x34, + 0x29,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61, + 0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x33,0x5d,0x26,0x44,0x61,0x74,0x61,0x73,0x65,0x74, + 0x45,0x78,0x74,0x72,0x61,0x49,0x74,0x65,0x6d,0x73,0x29,0x2a,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67, + 0x32,0x20,0x65,0x4d,0x61,0x73,0x6b,0x3d,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x32,0x2a,0x29,0x28,0x65,0x6e,0x74,0x72, + 0x6f,0x70,0x79,0x2b,0x31,0x34,0x29,0x3b,0x0a,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x78,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x4d, + 0x61,0x73,0x6b,0x2e,0x78,0x29,0x3b,0x0a,0x65,0x4d,0x61,0x73,0x6b,0x2e,0x79,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x4d,0x61, + 0x73,0x6b,0x2e,0x79,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31, + 0x36,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29, + 0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x6d,0x78,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x32,0x5d,0x3d,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3b, + 0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x33,0x5d, + 0x3d,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67, + 0x32,0x2a,0x29,0x28,0x52,0x2b,0x31,0x38,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x65,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e, + 0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3d,0x2d,0x31,0x3b,0x0a,0x5f,0x5f,0x67, + 0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, + 0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x28,0x52,0x45,0x47,0x49,0x53,0x54,0x45, + 0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53,0x49,0x5a,0x45,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e, + 0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73, + 0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a, + 0x7b,0x0a,0x69,0x66,0x28,0x21,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x5d,0x7c,0x7c,0x28,0x69,0x3d,0x3d,0x66,0x69, + 0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x7c,0x7c,0x28,0x28,0x69,0x3d,0x3d,0x66,0x69,0x72,0x73, + 0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73, + 0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66,0x70,0x29,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x20,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x66,0x70, + 0x5f,0x69,0x6e,0x73,0x74,0x73,0x3d,0x30,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3c, + 0x3d,0x6c,0x61,0x73,0x74,0x5f,0x75,0x73,0x65,0x64,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x26,0x26,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72, + 0x73,0x29,0x20,0x25,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x26,0x26,0x28,0x65,0x78,0x65,0x63,0x75,0x74,0x69, + 0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5d,0x7c,0x7c,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x7c, + 0x7c,0x28,0x28,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x3d,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74, + 0x69,0x6f,0x6e,0x5f,0x73,0x6c,0x6f,0x74,0x2b,0x31,0x29,0x26,0x26,0x66,0x69,0x72,0x73,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x5f,0x66, + 0x70,0x29,0x29,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x28,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x26,0x31,0x29,0x26,0x26,0x28,0x28,0x73,0x72,0x63, + 0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b,0x69,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f, + 0x72,0x6b,0x65,0x72,0x73,0x5d,0x5d,0x2e,0x78,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x29,0x29,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f, + 0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x2b,0x2b,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x7d,0x0a,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x28,0x28,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x2d,0x31,0x29,0x3c,0x3c,0x4e,0x55,0x4d,0x5f,0x49,0x4e,0x53, + 0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3c,0x3c,0x4e,0x55,0x4d,0x5f,0x46,0x50, + 0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x73,0x72,0x63,0x5f, + 0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x70,0x6c,0x61,0x6e,0x5b, + 0x69,0x5d,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x66,0x66,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e, + 0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, + 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32,0x34,0x29,0x3b,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x66,0x70,0x3d,0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x32,0x30,0x3c, + 0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x66,0x70,0x26,0x26,0x28,0x28,0x69,0x26,0x31,0x29,0x3d,0x3d,0x30,0x29,0x29,0x0a,0x2b, + 0x2b,0x69,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d, + 0x28,0x73,0x72,0x63,0x5f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x21,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73, + 0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x26,0x26,0x28,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73, + 0x6c,0x6f,0x74,0x3c,0x30,0x29,0x29,0x0a,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x6b,0x3b,0x0a,0x2b,0x2b, + 0x6b,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x32,0x29,0x20,0x25,0x20,0x34,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d, + 0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x64,0x73, + 0x74,0x21,0x3d,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4e,0x65,0x65,0x64,0x73,0x44,0x69,0x73,0x70,0x6c,0x61,0x63,0x65,0x6d,0x65,0x6e,0x74,0x29,0x0a,0x7b,0x0a, + 0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c, + 0x73,0x65,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54, + 0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d, + 0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75, + 0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64, + 0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46, + 0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f, + 0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d, + 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b, + 0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55, + 0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74, + 0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c, + 0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70, + 0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f, + 0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, + 0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53, + 0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, + 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46, + 0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a, + 0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65, + 0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f, + 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f, + 0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74, + 0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74, + 0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28, + 0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54, + 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c, + 0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31, + 0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d, + 0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d, + 0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28, + 0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e, + 0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a, + 0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67, + 0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69, + 0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42, + 0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f, + 0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73, + 0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45, + 0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d, + 0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e, + 0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d, + 0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d, + 0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f, + 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29, + 0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28, + 0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, + 0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, + 0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a, + 0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46, + 0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31, + 0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c, + 0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f, + 0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72, + 0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53, + 0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x36,0x3c,0x3c, + 0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72, + 0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, + 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48, + 0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48, + 0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73, + 0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74, + 0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f, + 0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x36,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44, + 0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d, + 0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58, + 0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e, + 0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31, + 0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c, + 0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e, + 0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78, + 0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65, + 0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46, + 0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x34,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70, + 0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65, + 0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, + 0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34, + 0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, + 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, + 0x54,0x29,0x7c,0x28,0x34,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69, + 0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28, + 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d, + 0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69, + 0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72, + 0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, + 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c, + 0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c, + 0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x3d,0x69,0x6d,0x75,0x6c,0x5f,0x72,0x63, + 0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3b,0x0a,0x69,0x66,0x28,0x72,0x3d,0x3d,0x31,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x63,0x6f, + 0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x7c,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28, + 0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d, + 0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e, + 0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78, + 0x5d,0x3d,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x72,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f, + 0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3d,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x2a,0x29,0x26,0x72,0x29,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d, 0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b, 0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50, - 0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46, - 0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69, - 0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53, - 0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d, - 0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b, - 0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b, - 0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b, - 0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64, - 0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, - 0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46, - 0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69, - 0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66, - 0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f, - 0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46, - 0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c, - 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29, - 0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c, - 0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73, - 0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46, - 0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44, - 0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52, - 0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67, - 0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69, - 0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c, - 0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f, - 0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72, - 0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46, - 0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53, + 0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x35,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28, + 0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44, + 0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x33,0x3c, + 0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a, + 0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c, + 0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d, + 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b, + 0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65, + 0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b, + 0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b, + 0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c, + 0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x33,0x3c,0x3c, + 0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65, + 0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f, + 0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b, + 0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43, + 0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49, + 0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69, + 0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53, + 0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x37,0x3c,0x3c, + 0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69, + 0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28, + 0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69, + 0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3e, + 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d, + 0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f, + 0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72, + 0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f, + 0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f, + 0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73, + 0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x38,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45, + 0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x28,0x28,0x73,0x72,0x63,0x21, + 0x3d,0x64,0x73,0x74,0x29,0x3f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3a,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x29,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65, + 0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54, + 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28, + 0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20, + 0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, + 0x7c,0x28,0x28,0x73,0x72,0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x28,0x53,0x52,0x43, + 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b, + 0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75, + 0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74, + 0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53, + 0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c, + 0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b, + 0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a, + 0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d, + 0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31, + 0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28, + 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32, + 0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70, + 0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65, + 0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67, + 0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x73,0x72, + 0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x28,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e, + 0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f, + 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63, + 0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46, + 0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e, + 0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52, + 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73, + 0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c, + 0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45, + 0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c, + 0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e, + 0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d, + 0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e, + 0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c, + 0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53, + 0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73, + 0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74, + 0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53, + 0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45, + 0x54,0x29,0x7c,0x28,0x33,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69, + 0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73, + 0x65,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b, + 0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, + 0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31, + 0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75, + 0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3d,0x30,0x78,0x38,0x30,0x46,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x69,0x6d,0x6d, + 0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61, + 0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75, + 0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f, + 0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52, + 0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e, + 0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46, + 0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x73,0x72,0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c, + 0x28,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, + 0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65, + 0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b, + 0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x28,0x64,0x73,0x74,0x20, + 0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e, + 0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46, + 0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x35,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45, 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d, 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f, 0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73, @@ -2419,17 +2677,40 @@ static const char randomx_cl[130953] = { 0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f, 0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c, 0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, - 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x7c,0x28,0x36,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65, - 0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b, - 0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61, - 0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32, - 0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63, - 0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x36, + 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28, + 0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x34,0x3c,0x3c,0x4f,0x50, + 0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, + 0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65, + 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48, + 0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x39,0x3c, + 0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, + 0x20,0x63,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x2b,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4f,0x66,0x66,0x73,0x65,0x74, + 0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x7c,0x28,0x31,0x55,0x3c,0x3c,0x63,0x73,0x68,0x69,0x66, + 0x74,0x29,0x3b,0x0a,0x69,0x66,0x28,0x63,0x73,0x68,0x69,0x66,0x74,0x3e,0x30,0x29,0x0a,0x69,0x6d,0x6d,0x20,0x26,0x3d,0x20,0x7e,0x28,0x31,0x55,0x3c,0x3c,0x28,0x63, + 0x73,0x68,0x69,0x66,0x74,0x2d,0x31,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45, + 0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d, + 0x69,0x6d,0x6d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3d,0x63,0x73,0x68,0x69,0x66,0x74, + 0x7c,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f,0x74,0x29, + 0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x69,0x6e,0x73, + 0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x7d,0x0a,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x5f,0x73,0x6c, + 0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73, + 0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73, + 0x74,0x2e,0x78,0x3d,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x33,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44, + 0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x36,0x33,0x29,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3e,0x3d,0x53,0x74,0x6f, + 0x72,0x65,0x4c,0x33,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29, + 0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c, + 0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x30, 0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e, 0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d, 0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78, @@ -2438,825 +2719,764 @@ static const char randomx_cl[130953] = { 0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78, 0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29, 0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d, - 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69, - 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a, - 0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c, - 0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x34,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b, - 0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75, - 0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x3b,0x0a,0x2a,0x28, + 0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77, + 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x7d,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28, + 0x52,0x2b,0x32,0x30,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72, + 0x6f,0x67,0x72,0x61,0x6d,0x2d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x28,0x52,0x45, + 0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53,0x49,0x5a,0x45,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f, + 0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6c,0x6f,0x61,0x64,0x5f,0x62,0x75,0x66, + 0x66,0x65,0x72,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x64,0x73,0x74,0x5f,0x62,0x75,0x66,0x2c,0x73,0x69, + 0x7a,0x65,0x5f,0x74,0x20,0x4e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x73,0x72,0x63,0x5f, + 0x62,0x75,0x66,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30, + 0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x20,0x73,0x74,0x65,0x70,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66, + 0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38, + 0x5f,0x74,0x2a,0x20,0x73,0x72,0x63,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74, + 0x2a,0x29,0x73,0x72,0x63,0x5f,0x62,0x75,0x66,0x29,0x2b,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f, + 0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x2a,0x4e,0x2b,0x69,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74, + 0x2a,0x20,0x64,0x73,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x64,0x73,0x74,0x5f,0x62,0x75,0x66, + 0x29,0x2b,0x69,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x69,0x3c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x2a,0x4e, + 0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x64,0x73,0x74,0x29,0x3d,0x2a,0x28, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x29,0x3b,0x0a,0x73,0x72,0x63,0x2b,0x3d,0x73, + 0x74,0x65,0x70,0x3b,0x0a,0x64,0x73,0x74,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x69,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x64,0x6f,0x75, + 0x62,0x6c,0x65,0x20,0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f,0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x69,0x6e,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x2c,0x75,0x69, + 0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x29,0x0a, + 0x7b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x3d,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x72,0x74,0x6e,0x28,0x76,0x61, + 0x6c,0x75,0x65,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x78,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x74,0x29,0x3b,0x0a,0x78,0x20, + 0x26,0x3d,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x78,0x7c,0x3d,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73, + 0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x78,0x29,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66,0x74,0x28,0x64,0x6f, + 0x75,0x62,0x6c,0x65,0x20,0x61,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x63,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, + 0x74,0x20,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d, + 0x6f,0x64,0x65,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x6d,0x61,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x3b,0x0a,0x69,0x66,0x28,0x28,0x61, + 0x3d,0x3d,0x30,0x2e,0x30,0x29,0x7c,0x7c,0x28,0x62,0x3d,0x3d,0x30,0x2e,0x30,0x29,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x63,0x3b,0x0a,0x69,0x66,0x28,0x62, + 0x3d,0x3d,0x31,0x2e,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x63,0x3d,0x3d,0x30,0x2e,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x3b,0x0a,0x69,0x66, + 0x28,0x63,0x3d,0x3d,0x2d,0x61,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x69,0x6e,0x75,0x73,0x5f,0x7a, + 0x65,0x72,0x6f,0x3d,0x31,0x55,0x4c,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f, + 0x64,0x65,0x3d,0x3d,0x31,0x29,0x3f,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x6d,0x69,0x6e,0x75,0x73,0x5f,0x7a,0x65,0x72,0x6f,0x29,0x3a,0x30,0x2e,0x30, + 0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x73,0x69, + 0x7a,0x65,0x3d,0x35,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x6d, + 0x61,0x73,0x6b,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20, + 0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x31,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, + 0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x31,0x3c,0x3c,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x73,0x69,0x7a,0x65, + 0x29,0x2d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,0x32,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x61,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32, + 0x20,0x62,0x32,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x62,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x32,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e, + 0x74,0x32,0x28,0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61, + 0x3d,0x28,0x61,0x32,0x2e,0x79,0x3e,0x3e,0x32,0x30,0x29,0x26,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x62,0x3d,0x28,0x62,0x32,0x2e,0x79,0x3e,0x3e,0x32,0x30,0x29,0x26, + 0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78, + 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x3d,0x28,0x63,0x32,0x2e,0x79,0x3e,0x3e,0x32,0x30,0x29,0x26,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73, + 0x6b,0x3b,0x0a,0x69,0x66,0x28,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x7c,0x7c,0x28,0x65,0x78,0x70,0x6f,0x6e, + 0x65,0x6e,0x74,0x5f,0x62,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x7c,0x7c,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29, + 0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x66,0x3d,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35, + 0x32,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69,0x6e,0x66,0x29,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x61,0x3d,0x61,0x32,0x2e,0x79,0x3e,0x3e,0x33,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x62,0x3d,0x62,0x32,0x2e,0x79,0x3e,0x3e,0x33,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x63,0x3d,0x63,0x32,0x2e,0x79,0x3e,0x3e,0x33,0x31,0x3b,0x0a,0x61,0x32,0x2e,0x79, + 0x3d,0x28,0x61,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29,0x29,0x7c,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x3b,0x0a,0x62, + 0x32,0x2e,0x79,0x3d,0x28,0x62,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29,0x29,0x7c,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29, + 0x3b,0x0a,0x63,0x32,0x2e,0x79,0x3d,0x28,0x63,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29,0x29,0x7c,0x28,0x31,0x55,0x3c,0x3c, + 0x32,0x30,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x61,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e, + 0x67,0x28,0x61,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x62,0x3d,0x61,0x73,0x5f,0x75,0x6c, + 0x6f,0x6e,0x67,0x28,0x62,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3d,0x61,0x73,0x5f, + 0x75,0x6c,0x6f,0x6e,0x67,0x28,0x63,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x32, + 0x5d,0x3b,0x0a,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x61,0x2a,0x6d,0x61,0x6e,0x74, + 0x69,0x73,0x73,0x61,0x5f,0x62,0x3b,0x0a,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x68,0x69,0x28,0x6d,0x61,0x6e, + 0x74,0x69,0x73,0x73,0x61,0x5f,0x61,0x2c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x62,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78, + 0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3e,0x3e,0x34,0x31,0x3b,0x0a, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x65,0x78,0x70, + 0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61,0x2b,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x62,0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f, + 0x6e,0x2d,0x31,0x30,0x32,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74, + 0x3d,0x73,0x69,0x67,0x6e,0x5f,0x61,0x5e,0x73,0x69,0x67,0x6e,0x5f,0x62,0x3b,0x0a,0x69,0x66,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f, + 0x72,0x65,0x73,0x75,0x6c,0x74,0x3e,0x3d,0x32,0x30,0x34,0x37,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69, + 0x6e,0x66,0x5f,0x72,0x6e,0x64,0x3d,0x28,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x2d,0x28,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f, + 0x64,0x65,0x26,0x31,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x29, + 0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x32,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74, + 0x36,0x34,0x5f,0x74,0x20,0x74,0x5b,0x32,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61, + 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3e, + 0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x32,0x33, + 0x2d,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d, + 0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b, + 0x31,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29,0x7c,0x28,0x6d,0x75,0x6c,0x5f,0x72, + 0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x29,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73, + 0x68,0x69,0x66,0x74,0x32,0x3d,0x28,0x31,0x32,0x37,0x2d,0x35,0x32,0x29,0x2b,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e, + 0x74,0x5f,0x63,0x2d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69, + 0x66,0x74,0x32,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d, + 0x30,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3c,0x3c,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x2d,0x36,0x34,0x29,0x3b, + 0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74, + 0x32,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x73,0x68,0x69,0x66,0x74,0x32,0x3f,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3e,0x3e,0x28,0x36,0x34,0x2d, + 0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3a,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x28,0x73,0x68,0x69, + 0x66,0x74,0x32,0x3c,0x2d,0x35,0x32,0x29,0x3f,0x30,0x3a,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3e,0x3e,0x28,0x2d,0x73,0x68,0x69,0x66,0x74,0x32, + 0x29,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x28,0x74,0x5b,0x30,0x5d,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x63,0x21,0x3d,0x30,0x2e, + 0x30,0x29,0x29,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x31,0x3b,0x0a,0x7d,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a, + 0x74,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3c,0x3c,0x31,0x31,0x3b,0x0a,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x32,0x3d,0x28,0x31,0x32,0x37,0x2d,0x31,0x30,0x34,0x2d,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74, + 0x69,0x6f,0x6e,0x29,0x2b,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75, + 0x6c,0x74,0x2d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a, + 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x3c,0x73,0x68,0x69, + 0x66,0x74,0x32,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31, + 0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3f,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30, + 0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3a,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x73,0x68,0x69, + 0x66,0x74,0x32,0x3d,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x73,0x68, + 0x69,0x66,0x74,0x32,0x2d,0x3d,0x36,0x34,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3c, + 0x36,0x34,0x29,0x3f,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x3a,0x30,0x3b,0x0a,0x66, + 0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d, + 0x3d,0x3d,0x30,0x29,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x31,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x66, + 0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x73,0x68,0x69, + 0x66,0x74,0x32,0x29,0x7c,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x29, + 0x29,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3e,0x3e, + 0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d, + 0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f, + 0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x3d,0x73,0x69,0x67,0x6e, + 0x5f,0x63,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x2b,0x3d,0x74,0x5b,0x30,0x5d,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72, + 0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x74,0x5b,0x31,0x5d,0x2b,0x28,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x74, + 0x5b,0x30,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x29,0x3b,0x0a,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72, + 0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x74,0x5b,0x31,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73, + 0x75,0x6c,0x74,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x63,0x6f, + 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x6f,0x72,0x72,0x6f,0x77,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b, + 0x30,0x5d,0x3c,0x74,0x5b,0x30,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x2d,0x3d,0x74,0x5b,0x30, + 0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x62,0x6f,0x72,0x72,0x6f,0x77,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, + 0x63,0x68,0x61,0x6e,0x67,0x65,0x5f,0x73,0x69,0x67,0x6e,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x74,0x5b,0x31,0x5d,0x29, + 0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2d,0x3d,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x73,0x69,0x67,0x6e,0x5f, + 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5e,0x63,0x68,0x61,0x6e,0x67, + 0x65,0x5f,0x73,0x69,0x67,0x6e,0x3b,0x0a,0x69,0x66,0x28,0x63,0x68,0x61,0x6e,0x67,0x65,0x5f,0x73,0x69,0x67,0x6e,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65, + 0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x2d,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d, + 0x29,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x7e,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3b, + 0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3f,0x30,0x3a, + 0x31,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x66, + 0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x65,0x78,0x70, + 0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2d,0x3d,0x36,0x34,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74, + 0x5b,0x31,0x5d,0x3d,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d, + 0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,0x63,0x6c,0x7a,0x28,0x66, + 0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x64,0x65,0x78,0x29,0x0a,0x7b,0x0a,0x65,0x78,0x70,0x6f,0x6e, + 0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2d,0x3d,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x5b,0x31,0x5d,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x69,0x6e,0x64,0x65,0x78,0x29,0x7c,0x28,0x66,0x6d,0x61, + 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x69,0x6e,0x64,0x65,0x78,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x78,0x70,0x5f,0x63, + 0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68, + 0x69,0x66,0x74,0x3d,0x31,0x31,0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e, + 0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x75,0x70,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x7c,0x7c,0x28, + 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x26,0x28,0x28,0x31,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29,0x2d,0x31,0x29,0x29,0x29,0x3f,0x31, + 0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x20,0x3e,0x3e,0x3d,0x20,0x73,0x68,0x69,0x66,0x74,0x3b,0x0a,0x66,0x6d,0x61, + 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x20,0x26,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x69,0x66,0x28, + 0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x2b,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x3d,0x32, + 0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x75,0x70,0x3b,0x0a,0x69,0x66,0x28, + 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x73,0x69, + 0x7a,0x65,0x29,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x2b,0x2b,0x65,0x78,0x70,0x6f,0x6e,0x65, + 0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d, + 0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74, + 0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x29,0x3c,0x3c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x73,0x69,0x7a,0x65,0x3b, + 0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x73,0x69,0x67,0x6e,0x5f, + 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c, + 0x65,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x64,0x69,0x76,0x5f,0x72, + 0x6e,0x64,0x28,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x61,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70, + 0x72,0x63,0x29,0x0a,0x7b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x79,0x30,0x3d,0x31,0x2e,0x30,0x2f,0x62,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75, + 0x62,0x6c,0x65,0x20,0x74,0x30,0x3d,0x61,0x2a,0x79,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x31,0x3d,0x66,0x6d,0x61, + 0x28,0x2d,0x62,0x2c,0x74,0x30,0x2c,0x61,0x29,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66, + 0x74,0x28,0x79,0x30,0x2c,0x74,0x31,0x2c,0x74,0x30,0x2c,0x66,0x70,0x72,0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, + 0x20,0x69,0x6e,0x66,0x3d,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20, + 0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x3d,0x69,0x6e,0x66,0x2d,0x28,0x66,0x70,0x72,0x63,0x26,0x31,0x29,0x3b,0x0a,0x69,0x66,0x28,0x28,0x28,0x61,0x73,0x5f,0x75,0x6c, + 0x6f,0x6e,0x67,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3e,0x3e,0x35,0x32,0x29,0x26,0x32,0x30,0x34,0x37,0x29,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x20,0x72,0x65, + 0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x29,0x3b,0x0a,0x69,0x66,0x28,0x61,0x73,0x5f,0x75, + 0x6c,0x6f,0x6e,0x67,0x28,0x61,0x29,0x3d,0x3d,0x69,0x6e,0x66,0x29,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28, + 0x61,0x3d,0x3d,0x62,0x29,0x3f,0x31,0x2e,0x30,0x3a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x73,0x71,0x72,0x74,0x5f, + 0x72,0x6e,0x64,0x28,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72,0x63,0x29,0x0a,0x7b,0x0a,0x64,0x6f, + 0x75,0x62,0x6c,0x65,0x20,0x79,0x30,0x3d,0x72,0x73,0x71,0x72,0x74,0x28,0x78,0x29,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x30,0x3d,0x79,0x30,0x2a,0x78, + 0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x31,0x3d,0x79,0x30,0x2a,0x2d,0x30,0x2e,0x35,0x3b,0x0a,0x74,0x31,0x3d,0x66,0x6d,0x61,0x28,0x74,0x31,0x2c,0x74, + 0x30,0x2c,0x30,0x2e,0x35,0x29,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x79,0x31,0x5f,0x78,0x3d,0x66, + 0x6d,0x61,0x28,0x74,0x30,0x2c,0x74,0x31,0x2c,0x74,0x30,0x29,0x3b,0x09,0x0a,0x79,0x30,0x20,0x2a,0x3d,0x20,0x30,0x2e,0x35,0x3b,0x0a,0x79,0x30,0x3d,0x66,0x6d,0x61, + 0x28,0x79,0x30,0x2c,0x74,0x31,0x2c,0x79,0x30,0x29,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x74,0x31,0x3d,0x66,0x6d,0x61,0x28,0x2d,0x79,0x31,0x5f,0x78,0x2c,0x79,0x31, + 0x5f,0x78,0x2c,0x78,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66, + 0x74,0x28,0x74,0x31,0x2c,0x79,0x30,0x2c,0x79,0x31,0x5f,0x78,0x2c,0x66,0x70,0x72,0x63,0x29,0x3b,0x09,0x09,0x0a,0x69,0x66,0x28,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74, + 0x36,0x34,0x5f,0x74,0x2a,0x29,0x20,0x26,0x78,0x29,0x3d,0x3d,0x28,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x29,0x20,0x72,0x65,0x73,0x75,0x6c,0x74, + 0x3d,0x78,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e, + 0x6e,0x65,0x72,0x5f,0x6c,0x6f,0x6f,0x70,0x28,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, + 0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a, + 0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, + 0x20,0x73,0x75,0x62,0x2c,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70, + 0x61,0x64,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74, + 0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f, + 0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x52,0x2c,0x0a,0x5f,0x5f,0x6c, + 0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72,0x63, + 0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b, + 0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x2c,0x0a, + 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x0a,0x29,0x0a,0x7b,0x0a, + 0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x32,0x3d,0x73,0x75,0x62,0x3e,0x3e,0x31,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62, + 0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3d,0x66,0x70,0x72,0x63,0x3b,0x0a,0x23,0x70,0x72,0x61, + 0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x70,0x3d,0x30,0x3b,0x20, + 0x69,0x70,0x3c,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d, + 0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3d,0x69,0x70,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74, + 0x3d,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x70,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4e,0x55,0x4d,0x5f,0x49,0x4e,0x53,0x54, + 0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2d,0x31,0x29,0x3b,0x0a, + 0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3d,0x28,0x69,0x6e,0x73,0x74, + 0x3e,0x3e,0x4e,0x55,0x4d,0x5f,0x46,0x50,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f, + 0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x69, + 0x6e,0x73,0x74,0x73,0x3d,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x2d,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x69, + 0x66,0x28,0x73,0x75,0x62,0x3c,0x3d,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x75,0x62,0x2d,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73, + 0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x66,0x70,0x3d,0x69,0x6e,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3c,0x6e, + 0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x3d,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72, + 0x61,0x6d,0x5b,0x69,0x70,0x2b,0x28,0x69,0x73,0x5f,0x66,0x70,0x3f,0x73,0x75,0x62,0x32,0x3a,0x69,0x6e,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x5d,0x3b, + 0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f, + 0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x31,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, + 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x69,0x73,0x5f,0x66,0x70,0x3f,0x34,0x3a,0x33, + 0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74, + 0x3d,0x69,0x73,0x5f,0x66,0x70,0x3f,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3a,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x69,0x73,0x5f,0x66,0x70, + 0x3f,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, + 0x26,0x37,0x3b,0x0a,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28, + 0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3c,0x3c,0x72,0x65,0x67,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x73,0x68,0x69,0x66,0x74,0x29,0x3b,0x0a,0x75,0x69,0x6e, + 0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53, + 0x45,0x54,0x29,0x26,0x37,0x3b,0x0a,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3c,0x3c,0x33, + 0x29,0x2b,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3f,0x30,0x3a,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65, + 0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x3d,0x28,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38, + 0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, + 0x2a,0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66, + 0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d, + 0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x32,0x35,0x35,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20, + 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x70,0x74,0x72,0x3d,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2b, + 0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d,0x2a,0x64,0x73,0x74,0x5f,0x70,0x74, + 0x72,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x2a,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20, + 0x69,0x6d,0x6d,0x3b,0x0a,0x69,0x6d,0x6d,0x2e,0x78,0x3d,0x69,0x6d,0x6d,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6d,0x6d,0x2e,0x79,0x3d,0x69,0x6d,0x6d, + 0x5f,0x70,0x74,0x72,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x3e,0x3e,0x32,0x31,0x29,0x26,0x33,0x31,0x3b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, + 0x55,0x3e,0x3e,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x29,0x2d,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x72, + 0x65,0x61,0x64,0x3d,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x21,0x3d,0x31,0x30,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,0x64,0x64,0x72,0x3d, + 0x69,0x73,0x5f,0x72,0x65,0x61,0x64,0x3f,0x28,0x28,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x3d,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x3f,0x30,0x3a,0x28, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x3a,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x3b, + 0x0a,0x61,0x64,0x64,0x72,0x2b,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x20,0x26,0x3d, + 0x20,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x74,0x72,0x3d,0x28,0x5f, + 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x61,0x64, + 0x64,0x72,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x72,0x65,0x61,0x64,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x3d,0x2a,0x70,0x74,0x72,0x3b,0x0a,0x7d,0x0a,0x65, + 0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x70,0x74,0x72,0x3d,0x73,0x72,0x63,0x3b,0x0a,0x67,0x6f,0x74,0x6f,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65, + 0x6e,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d, + 0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x69,0x6e,0x74,0x36, + 0x34,0x5f,0x74,0x29,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x3d,0x33,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52, + 0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x2d,0x28,0x69,0x6e,0x74,0x36, + 0x34,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x30,0x29,0x20,0x64,0x73,0x74,0x2b,0x3d,0x28, + 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, + 0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x33,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x32,0x29,0x20,0x64,0x73,0x74,0x2b,0x3d,0x73,0x72,0x63,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x36,0x34,0x3d,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x20,0x26, + 0x69,0x6d,0x6d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x36,0x34,0x5f,0x4f, + 0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x69,0x6d,0x6d,0x36,0x34,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x32,0x29, + 0x20,0x64,0x73,0x74,0x20,0x2a,0x3d,0x20,0x73,0x72,0x63,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x33,0x29,0x20,0x64,0x73,0x74,0x20,0x5e, + 0x3d,0x20,0x73,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x32,0x29,0x0a,0x7b,0x0a,0x69, + 0x66,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x29,0x20,0x73,0x72,0x63,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74, + 0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x72,0x74,0x6e,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x3e,0x3e,0x28,0x28,0x73,0x75,0x62, + 0x26,0x31,0x29,0x2a,0x33,0x32,0x29,0x29,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45, + 0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x6d,0x75,0x6c,0x3d,0x28,0x69,0x6e, + 0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x21,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x61,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x64,0x73,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64, + 0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x73,0x72,0x63,0x29,0x3b,0x0a,0x64,0x73,0x74,0x3d,0x61,0x73,0x5f,0x75, + 0x6c,0x6f,0x6e,0x67,0x28,0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66,0x74,0x28,0x61,0x2c,0x69,0x73,0x5f,0x6d,0x75,0x6c,0x3f,0x62,0x3a,0x31,0x2e,0x30,0x2c,0x69,0x73,0x5f, + 0x6d,0x75,0x6c,0x3f,0x30,0x2e,0x30,0x3a,0x62,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3d,0x3d,0x39,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x2b,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a, + 0x69,0x66,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x26,0x28,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61, + 0x73,0x6b,0x3c,0x3c,0x28,0x69,0x6d,0x6d,0x2e,0x79,0x26,0x33,0x31,0x29,0x29,0x29,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49, + 0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x28,0x28,0x69,0x6e,0x74, + 0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x79,0x29,0x3e,0x3e,0x35,0x29,0x2d,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x73,0x29,0x3b,0x0a,0x7d,0x0a,0x7d, + 0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x37,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73, + 0x68,0x69,0x66,0x74,0x31,0x3d,0x73,0x72,0x63,0x26,0x36,0x33,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, + 0x52,0x4f,0x4c,0x5f,0x52,0x20,0x3e,0x20,0x30,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x32,0x3d, + 0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x72,0x6f,0x6c,0x3d,0x28,0x69,0x6e, + 0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x3b,0x0a,0x64,0x73, + 0x74,0x3d,0x28,0x64,0x73,0x74,0x3e,0x3e,0x28,0x69,0x73,0x5f,0x72,0x6f,0x6c,0x3f,0x73,0x68,0x69,0x66,0x74,0x32,0x3a,0x73,0x68,0x69,0x66,0x74,0x31,0x29,0x29,0x7c, + 0x28,0x64,0x73,0x74,0x3c,0x3c,0x28,0x69,0x73,0x5f,0x72,0x6f,0x6c,0x3f,0x73,0x68,0x69,0x66,0x74,0x31,0x3a,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3b,0x0a,0x23, + 0x65,0x6c,0x73,0x65,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x28,0x36,0x34, + 0x2d,0x73,0x68,0x69,0x66,0x74,0x31,0x29,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3d,0x3d,0x31,0x34,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x73,0x71,0x72,0x74,0x5f,0x72,0x6e,0x64,0x28, + 0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x64,0x73,0x74,0x29,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x36,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x6d,0x75,0x6c,0x5f,0x68,0x69,0x28,0x64,0x73,0x74,0x2c,0x73,0x72,0x63, + 0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x34,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x75, + 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x6d,0x75,0x6c,0x5f,0x68,0x69,0x28,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x2c,0x28, + 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x3d,0x3d,0x31,0x31,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x2a,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, + 0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b,0x28,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66, + 0x73,0x65,0x74,0x5e,0x38,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x38,0x29,0x0a,0x7b,0x0a, + 0x2a,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3d,0x64,0x73,0x74,0x3b,0x0a,0x64,0x73,0x74,0x3d,0x73,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x35,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x63,0x6f,0x6e,0x76, + 0x65,0x72,0x74,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x72,0x74,0x6e,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x3e,0x3e,0x28,0x28, + 0x73,0x75,0x62,0x26,0x31,0x29,0x2a,0x33,0x32,0x29,0x29,0x29,0x29,0x3b,0x0a,0x73,0x72,0x63,0x20,0x26,0x3d,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e, + 0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x73,0x72,0x63,0x7c,0x3d,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x64, + 0x73,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x64,0x69,0x76,0x5f,0x72,0x6e,0x64,0x28,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x64,0x73, + 0x74,0x29,0x2c,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x73,0x72,0x63,0x29,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65, + 0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x35,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28, + 0x2d,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x52,0x4f,0x55,0x4e, + 0x44,0x49,0x4e,0x47,0x5f,0x4d,0x4f,0x44,0x45,0x3c,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58, + 0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3d,0x28,0x28,0x73,0x72,0x63,0x3e,0x3e,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x7c,0x28,0x73,0x72, + 0x63,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0x26,0x33,0x3b,0x0a,0x67,0x6f,0x74,0x6f,0x20,0x65,0x78,0x65, + 0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65,0x6e,0x64,0x3b,0x0a,0x7d,0x0a,0x2a,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x3d,0x64,0x73,0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a, + 0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65,0x6e,0x64,0x3a,0x0a,0x7b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43, + 0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x70,0x3d,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e, + 0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3b,0x0a,0x66,0x70,0x72,0x63,0x3d,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44, + 0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x70,0x2b,0x3d,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x73,0x2b,0x31,0x3b,0x0a,0x7d,0x0a, + 0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x70,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x23,0x69,0x66,0x20,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52, + 0x5f,0x48,0x41,0x53,0x48,0x20,0x3d,0x3d,0x20,0x31,0x36,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f, + 0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a, + 0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73, + 0x69,0x7a,0x65,0x28,0x31,0x36,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f, + 0x69,0x64,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x5f,0x76,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x76,0x6d,0x5f, + 0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x2c,0x5f, + 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x5f,0x70,0x74,0x72,0x2c,0x75,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x69,0x74,0x65,0x72, + 0x61,0x74,0x69,0x6f,0x6e,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c, + 0x61,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65, + 0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5b,0x28,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x32,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66, + 0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x6c,0x6f,0x61,0x64,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74, + 0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x2c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x29, + 0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x2c,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x3b,0x0a,0x62,0x61, + 0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x65,0x6e,0x75,0x6d, + 0x20,0x7b,0x20,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x3d,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3d,0x3d, + 0x31,0x36,0x29,0x3f,0x31,0x36,0x3a,0x38,0x20,0x7d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x52,0x3d, + 0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x2b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29, + 0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x2a,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66, + 0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x46,0x3d,0x28,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x38,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f, + 0x75,0x62,0x6c,0x65,0x2a,0x20,0x45,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x3b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74, + 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64,0x78, + 0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x25,0x20,0x49,0x44,0x58,0x5f,0x57,0x49, + 0x44,0x54,0x48,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x61,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33, + 0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x78,0x3d,0x28,0x28,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3d,0x28,0x28,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x32,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c, + 0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x30,0x3d,0x28,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, + 0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x30,0x78,0x66,0x66,0x29,0x29, + 0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65, + 0x67,0x31,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c, + 0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3e, + 0x3e,0x38,0x29,0x26,0x30,0x78,0x66,0x66,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x32,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29, + 0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73, + 0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3e,0x3e,0x31,0x36,0x29,0x26,0x30,0x78,0x66,0x66,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63, + 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x33,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c, + 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52, + 0x29,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3e,0x3e,0x32,0x34,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x33,0x5d,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, + 0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x5f,0x70,0x74,0x72,0x29,0x2b,0x64, + 0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f, + 0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x36,0x34,0x2b,0x28,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x26,0x31,0x29,0x3c, + 0x3c,0x33,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67,0x72,0x6f,0x75,0x70, + 0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x31,0x39,0x32,0x2b,0x28,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x26,0x31,0x29,0x3c, + 0x3c,0x33,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x65,0x4d,0x61,0x73,0x6b,0x3d,0x52,0x2b,0x31, + 0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68, + 0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x32,0x30,0x29,0x29,0x5b,0x30,0x5d,0x3b, + 0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72,0x63,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x2a,0x29,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x29,0x5b,0x69,0x64,0x78,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x70,0x41, + 0x64,0x64,0x72,0x30,0x3d,0x66,0x69,0x72,0x73,0x74,0x3f,0x6d,0x78,0x3a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x70,0x41,0x64,0x64,0x72, + 0x31,0x3d,0x66,0x69,0x72,0x73,0x74,0x3f,0x6d,0x61,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20, + 0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x73, + 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x33,0x2b,0x36,0x34,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c, + 0x20,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3d,0x28,0x73,0x75,0x62,0x3c,0x34,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65, + 0x2a,0x20,0x66,0x65,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x28,0x46,0x2b,0x73,0x75,0x62,0x2a,0x32,0x29,0x3a,0x28,0x45,0x2b,0x28,0x73,0x75,0x62,0x2d,0x34, + 0x29,0x2a,0x32,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x66,0x3d,0x46,0x2b,0x73,0x75,0x62,0x3b,0x0a,0x5f, + 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x65,0x3d,0x45,0x2b,0x73,0x75,0x62,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, + 0x29,0x28,0x2d,0x31,0x29,0x3a,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x31,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x30,0x3a,0x65,0x4d,0x61,0x73, + 0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x32,0x3d,0x66,0x5f,0x67, + 0x72,0x6f,0x75,0x70,0x3f,0x30,0x3a,0x65,0x4d,0x61,0x73,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20, + 0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x3d,0x28,0x73,0x75,0x62,0x26,0x31,0x29,0x3f,0x65,0x4d,0x61,0x73,0x6b,0x5b,0x31,0x5d,0x3a,0x65, + 0x4d,0x61,0x73,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62, + 0x75,0x66,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x52,0x45,0x47,0x49,0x53,0x54,0x45, + 0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63, + 0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67, + 0x72,0x61,0x6d,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b, + 0x28,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53,0x49,0x5a,0x45,0x29,0x2f,0x73,0x69, + 0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, + 0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x28,0x31,0x3c,0x3c,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41, + 0x53,0x48,0x29,0x2d,0x31,0x29,0x3c,0x3c,0x28,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49, + 0x44,0x54,0x48,0x29,0x2a,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, + 0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x33,0x3c,0x3c,0x28,0x28,0x28,0x73,0x75,0x62,0x3e,0x3e,0x31,0x29,0x3c,0x3c,0x31, + 0x29,0x2b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x2a,0x49,0x44, + 0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28, + 0x69,0x6e,0x74,0x20,0x69,0x63,0x3d,0x30,0x3b,0x20,0x69,0x63,0x3c,0x6e,0x75,0x6d,0x5f,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x73,0x3b,0x20,0x2b,0x2b,0x69, + 0x63,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x72,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x70,0x30,0x2c,0x2a,0x70,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53, + 0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3c,0x3d,0x38,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x73,0x70,0x4d,0x69,0x78,0x3d,0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x30,0x5e,0x2a,0x72,0x65,0x61,0x64,0x52,0x65, + 0x67,0x31,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x20,0x5e,0x3d,0x20,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a, + 0x29,0x26,0x73,0x70,0x4d,0x69,0x78,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x20,0x5e,0x3d,0x20,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x73,0x70,0x4d,0x69,0x78,0x29,0x5b,0x31,0x5d,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x20,0x26,0x3d, + 0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x20,0x26,0x3d,0x20, + 0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x3b,0x0a,0x70,0x30,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, + 0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x2b,0x73, + 0x75,0x62,0x2a,0x38,0x29,0x3b,0x0a,0x70,0x31,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73, + 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x2b,0x73,0x75,0x62,0x2a,0x38,0x29,0x3b,0x0a,0x72,0x3d,0x52,0x2b,0x73,0x75, + 0x62,0x3b,0x0a,0x2a,0x72,0x20,0x5e,0x3d,0x20,0x2a,0x70,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x6d,0x65, + 0x6d,0x5f,0x64,0x61,0x74,0x61,0x3d,0x2a,0x70,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x71,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a, + 0x29,0x26,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x6d,0x65,0x6d,0x5f,0x64,0x61,0x74,0x61,0x3b,0x0a,0x66,0x65,0x5b,0x30,0x5d,0x3d,0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f, + 0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x71,0x5b,0x30,0x5d,0x2c,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x2c,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x31,0x29,0x3b,0x0a, + 0x66,0x65,0x5b,0x31,0x5d,0x3d,0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f,0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x71,0x5b,0x31,0x5d,0x2c,0x61,0x6e,0x64,0x4d,0x61, + 0x73,0x6b,0x2c,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48, + 0x41,0x53,0x48,0x3d,0x3d,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45, + 0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x29,0x0a,0x66,0x70,0x72,0x63,0x3d,0x69,0x6e,0x6e,0x65,0x72,0x5f,0x6c,0x6f,0x6f,0x70,0x28,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, + 0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2c,0x73,0x75,0x62,0x2c,0x73,0x63,0x72, + 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67,0x72,0x6f, + 0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x52,0x2c,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65, + 0x2c,0x66,0x70,0x72,0x63,0x2c,0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x2c,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d, + 0x61,0x73,0x6b,0x2c,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x29,0x3b,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50, + 0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3c,0x3d,0x38,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x6d,0x78,0x20,0x5e,0x3d,0x20,0x2a,0x72, + 0x65,0x61,0x64,0x52,0x65,0x67,0x32,0x5e,0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x33,0x3b,0x0a,0x6d,0x78,0x20,0x26,0x3d,0x20,0x43,0x61,0x63,0x68,0x65,0x4c,0x69, + 0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6e,0x65,0x78,0x74, + 0x5f,0x72,0x3d,0x2a,0x72,0x5e,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, + 0x29,0x28,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x2b,0x6d,0x61,0x2b,0x73,0x75,0x62,0x2a,0x38,0x29,0x3b,0x0a,0x2a,0x72,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x72,0x3b,0x0a, + 0x2a,0x70,0x31,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x72,0x3b,0x0a,0x2a,0x70,0x30,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x66,0x5b,0x30,0x5d,0x29,0x5e,0x61, + 0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x65,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x6d,0x70,0x3d,0x6d,0x61,0x3b,0x0a, + 0x6d,0x61,0x3d,0x6d,0x78,0x3b,0x0a,0x6d,0x78,0x3d,0x74,0x6d,0x70,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x3d,0x30,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72, + 0x31,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3e,0x38,0x29, + 0x26,0x26,0x28,0x73,0x75,0x62,0x3e,0x3d,0x38,0x29,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x76,0x6d, + 0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x28,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65, + 0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x52,0x5b,0x73,0x75,0x62,0x5d,0x3b,0x0a,0x69,0x66, + 0x28,0x73,0x75,0x62,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29, + 0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x29,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x66,0x70,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x6c,0x61,0x73,0x74,0x29,0x0a, + 0x7b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x2b,0x38,0x5d,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x46,0x5b,0x73,0x75,0x62,0x5d,0x29,0x5e,0x61,0x73,0x5f,0x75, + 0x6c,0x6f,0x6e,0x67,0x28,0x45,0x5b,0x73,0x75,0x62,0x5d,0x29,0x3b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x2b,0x31,0x36,0x5d,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67, + 0x28,0x45,0x5b,0x73,0x75,0x62,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x73,0x75,0x62,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x28,0x28, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x70,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x6d,0x61, + 0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x70,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31, + 0x5d,0x3d,0x6d,0x78,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f, + 0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c, + 0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6e,0x64,0x5f,0x73,0x68,0x61,0x72,0x65,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x72,0x67,0x65, + 0x74,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20, + 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x68,0x61,0x72,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, + 0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29, + 0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x34,0x2b,0x33,0x5d,0x3c,0x74,0x61, + 0x72,0x67,0x65,0x74,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69, + 0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x68,0x61,0x72,0x65,0x73,0x2b,0x30,0x78,0x46,0x46,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x64,0x78,0x3c,0x30,0x78,0x46,0x46,0x29, + 0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x73,0x74,0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e,0x49,0x54,0x49,0x41,0x4c,0x5f,0x48, + 0x41,0x53,0x48,0x5f,0x53,0x49,0x5a,0x45,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e,0x54,0x45,0x52,0x4d,0x45,0x44,0x49,0x41,0x54,0x45, + 0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53, + 0x49,0x5a,0x45,0x20,0x2a,0x20,0x31,0x36,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x4d,0x50,0x49,0x4c,0x45,0x44,0x5f,0x50,0x52,0x4f,0x47,0x52, + 0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x30,0x30,0x34,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d,0x5f,0x56,0x47,0x50,0x52,0x5f,0x52, + 0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x20,0x31,0x32,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a, + 0x65,0x20,0x35,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x20,0x31,0x31,0x0a,0x23,0x64,0x65, + 0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x6d,0x61,0x6e,0x74,0x69, + 0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61, + 0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23, + 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x20,0x31,0x30,0x32,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65, + 0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x73, + 0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x63,0x6f,0x6e,0x73, + 0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x30,0x78,0x33,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x64,0x79,0x6e,0x61, + 0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73, + 0x73,0x61,0x53,0x69,0x7a,0x65,0x20,0x2b,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x29,0x29,0x20,0x2d, + 0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67, + 0x20,0x33,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67, + 0x20,0x33,0x39,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67, + 0x20,0x35,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x20,0x28,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x33,0x20,0x2d,0x20,0x38,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65, + 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x42,0x49,0x54,0x53,0x20,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x20,0x38,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49, + 0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x53,0x45,0x54,0x50,0x43,0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32, + 0x5f,0x31,0x33,0x20,0x30,0x78,0x62,0x65,0x38,0x30,0x32,0x30,0x30,0x63,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33, + 0x32,0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x20,0x30,0x78,0x33,0x36,0x33,0x38,0x30,0x30,0x30,0x65,0x75,0x0a,0x23,0x64,0x65,0x66,0x69, + 0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x58,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41, + 0x44,0x5f,0x4c,0x4f,0x41,0x44,0x20,0x30,0x78,0x64,0x63,0x33,0x34,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x57,0x41,0x49, + 0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x62,0x66,0x38,0x63,0x33,0x66,0x37,0x30, + 0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48, + 0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x64,0x37,0x36,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f, + 0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x20,0x30,0x78,0x39,0x61,0x38,0x66,0x31,0x30,0x31,0x30,0x75,0x0a,0x23,0x64, + 0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x20,0x30,0x78,0x39,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x75, + 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x5f,0x32,0x20,0x30, + 0x78,0x39,0x61,0x38,0x66,0x66,0x66,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f, + 0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x20,0x30,0x78,0x39,0x61,0x61,0x31,0x30,0x65,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56, + 0x5f,0x42,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x33,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, + 0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x39,0x61,0x38,0x66,0x32,0x30, + 0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x20,0x30,0x78,0x38,0x39,0x30,0x30,0x30, + 0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x58,0x4f,0x52,0x5f,0x52,0x20,0x30,0x78,0x62, + 0x65,0x62,0x65,0x30,0x33,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x52,0x20,0x30,0x78,0x39,0x30,0x30,0x30,0x30,0x30, + 0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x20,0x30,0x78,0x38,0x66,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23, + 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4f,0x52,0x20,0x30,0x78,0x38,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x53,0x5f,0x41,0x4e,0x44,0x20,0x30,0x78,0x38,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x42,0x46,0x45,0x20, + 0x30,0x78,0x39,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x53,0x5f,0x53,0x57,0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42, + 0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x20,0x30,0x78,0x64,0x38,0x64,0x34,0x38,0x30,0x30,0x31,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56, + 0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x35,0x36,0x34,0x30,0x30,0x33,0x63,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41, + 0x4e,0x44,0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x33,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41, + 0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x46,0x50,0x20, + 0x30,0x78,0x64,0x63,0x33,0x30,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x20,0x30,0x78, + 0x33,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x4d,0x55,0x4c,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x35, + 0x36,0x35,0x30,0x30,0x34,0x34,0x75,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x53,0x45,0x54,0x50,0x43,0x5f,0x42,0x36, + 0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x20,0x30,0x78,0x62,0x65,0x38,0x30,0x31,0x64,0x30,0x63,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41, + 0x4e,0x44,0x5f,0x42,0x33,0x32,0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x20,0x30,0x78,0x32,0x36,0x33,0x38,0x30,0x30,0x30,0x65,0x75,0x0a, + 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x58,0x32,0x5f,0x53,0x43,0x52,0x41, + 0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x20,0x30,0x78,0x64,0x63,0x35,0x34,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x62,0x66,0x38, + 0x63,0x30,0x66,0x37,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f,0x53,0x43, + 0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69, + 0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x20,0x30,0x78,0x39,0x36,0x30,0x66,0x31,0x30,0x31, + 0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x20,0x30,0x78,0x39,0x32,0x30,0x30, + 0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f, + 0x52,0x5f,0x32,0x20,0x30,0x78,0x39,0x36,0x30,0x66,0x66,0x66,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49, + 0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x20,0x30,0x78,0x39,0x36,0x32,0x31,0x30,0x65,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x30,0x66,0x66,0x75,0x0a,0x23, + 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x39, + 0x36,0x30,0x66,0x32,0x30,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x20,0x30,0x78, + 0x38,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x58,0x4f,0x52,0x5f, + 0x52,0x20,0x30,0x78,0x62,0x65,0x62,0x65,0x30,0x30,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x52,0x20,0x30,0x78,0x38, + 0x66,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x20,0x30,0x78,0x38,0x65,0x30,0x30,0x30,0x30, + 0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4f,0x52,0x20,0x30,0x78,0x38,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65, + 0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x41,0x4e,0x44,0x20,0x30,0x78,0x38,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53, + 0x5f,0x42,0x46,0x45,0x20,0x30,0x78,0x39,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x53,0x5f,0x53,0x57,0x49,0x5a, + 0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x20,0x30,0x78,0x64,0x38,0x37,0x61,0x38,0x30,0x30,0x31,0x75,0x0a,0x23,0x64,0x65,0x66, + 0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x32,0x38,0x30,0x30,0x30,0x33,0x63,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, + 0x65,0x20,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x32,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, + 0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41, + 0x44,0x5f,0x46,0x50,0x20,0x30,0x78,0x64,0x63,0x35,0x30,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x58,0x4f,0x52,0x5f,0x42, + 0x33,0x32,0x20,0x30,0x78,0x32,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x4d,0x55,0x4c,0x5f,0x46,0x36,0x34, + 0x20,0x30,0x78,0x64,0x32,0x38,0x31,0x30,0x30,0x34,0x34,0x75,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x5f, + 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d, + 0x6d,0x33,0x32,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, + 0x65,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x31,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29, + 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32, + 0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x7c,0x28,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x72,0x65,0x74, + 0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61, + 0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x33,0x32,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68, + 0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x66,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20, + 0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x0a,0x7b,0x0a,0x23,0x69, + 0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x47,0x4c,0x4f,0x42,0x41, + 0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x58,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x3b,0x0a, + 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c, + 0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x35,0x34,0x33,0x39,0x30,0x32,0x75,0x3b,0x09,0x09, + 0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x31,0x31,0x63,0x36,0x61,0x32,0x62,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x31,0x61,0x39,0x30,0x31,0x30,0x33,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x63,0x35,0x34, + 0x30,0x30,0x30,0x30,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x61,0x75,0x7c, + 0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70, + 0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76, + 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e, + 0x3d,0x30,0x29,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f, + 0x4c,0x4f,0x41,0x44,0x32,0x7c,0x28,0x76,0x6d,0x63,0x6e,0x74,0x26,0x31,0x35,0x29,0x7c,0x28,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e,0x3e,0x34,0x29,0x3c,0x3c,0x31,0x34, + 0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48, + 0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x31,0x34,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x30,0x30,0x75, + 0x7c,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42, + 0x33,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x31,0x35,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, + 0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x30,0x30,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72, + 0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63, + 0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, + 0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x33,0x32,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6d, + 0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x38,0x31,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69, + 0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x7c,0x30,0x78,0x33,0x38,0x30,0x30,0x30,0x65,0x75, + 0x7c,0x28,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20, + 0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x34,0x61,0x33,0x38,0x35,0x39,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6c,0x69,0x66,0x20, + 0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3d,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x36,0x38,0x33,0x38,0x35, + 0x39,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x33,0x38,0x35,0x39,0x31,0x63,0x75,0x3b,0x0a, + 0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, + 0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, + 0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x47,0x4c,0x4f,0x42,0x41,0x4c, + 0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x46,0x50,0x3b,0x0a, + 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c, + 0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x35,0x34,0x33,0x39,0x30,0x32,0x75,0x3b,0x09,0x09, + 0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x31,0x31,0x63,0x36,0x61,0x32,0x62,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x31,0x61,0x39,0x30,0x31,0x30,0x33,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x63,0x35,0x30, + 0x30,0x30,0x30,0x30,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x61,0x75,0x7c, + 0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70, + 0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x5f,0x66,0x70,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e, + 0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x76,0x6d,0x63, + 0x6e,0x74,0x3e,0x3d,0x30,0x29,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50, + 0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x28,0x76,0x6d,0x63,0x6e,0x74,0x26,0x31,0x35,0x29,0x7c,0x28,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e,0x3e,0x34,0x29,0x3c, + 0x3c,0x31,0x34,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x39,0x30,0x30,0x75,0x7c,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20, + 0x6a,0x69,0x74,0x5f,0x65,0x6d,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, + 0x6e,0x74,0x2a,0x20,0x70,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68, + 0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x2c,0x69,0x6e,0x74,0x20,0x70,0x72,0x65, + 0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20, + 0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78, + 0x26,0x30,0x78,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38, + 0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29, + 0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32,0x34,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x32,0x29,0x20,0x25,0x20,0x34,0x3b,0x0a, + 0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x3e,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x38, + 0x65,0x38,0x30,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37, + 0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28, + 0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31, + 0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c, + 0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c, + 0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x64,0x73,0x74,0x3d,0x3d,0x35,0x29, + 0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c, + 0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c, + 0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x3f,0x30,0x78,0x63,0x31,0x3a,0x30,0x78,0x38,0x30,0x29,0x3c, + 0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, + 0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a, + 0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63, + 0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61, + 0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63, + 0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f, + 0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61, + 0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f, + 0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d, + 0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d, + 0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, + 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a, + 0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b, + 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73, + 0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72, + 0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64, + 0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x31,0x31,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29, + 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30, + 0x39,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x30,0x30,0x31,0x31,0x75,0x7c,0x28,0x64, + 0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6e,0x73,0x74,0x2e, + 0x79,0x29,0x3c,0x30,0x29,0x3f,0x30,0x78,0x63,0x31,0x3a,0x30,0x78,0x38,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70, + 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x3b, + 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a, + 0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69, + 0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61, + 0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34, + 0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, + 0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70, + 0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65, + 0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74, + 0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28, + 0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, + 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70, + 0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c, + 0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66, + 0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, + 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x30,0x65, + 0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, + 0x78,0x38,0x32,0x39,0x31,0x30,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d, + 0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47, + 0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49, + 0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x23, + 0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29, + 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30, + 0x30,0x30,0x30,0x32,0x31,0x31,0x63,0x75,0x2b,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38, + 0x39,0x30,0x30,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64, + 0x69,0x66,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x31,0x31,0x31, + 0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38, + 0x30,0x30,0x66,0x30,0x65,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c, + 0x30,0x78,0x30,0x65,0x31,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a, + 0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, + 0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x5f,0x32,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33, + 0x38,0x30,0x32,0x66,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, + 0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x32,0x31,0x31,0x63,0x75,0x2b,0x28,0x64, + 0x73,0x74,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x61,0x73,0x5f,0x69,0x6e, + 0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x38,0x66,0x31,0x30,0x30, + 0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f, + 0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x66,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30, + 0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a, + 0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c, + 0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c, + 0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62, + 0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70, + 0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53, + 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a, + 0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, + 0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29, + 0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b, + 0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74, + 0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a, + 0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23, + 0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29, + 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30, + 0x30,0x30,0x30,0x31,0x64,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x32,0x31,0x75,0x3b,0x0a,0x2a,0x28, + 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x32,0x30,0x30,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31, + 0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x32,0x31,0x32,0x30,0x32,0x31,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f, + 0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x32,0x30,0x30,0x65,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b, + 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x32,0x30,0x32,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28, + 0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d, + 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a, + 0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62, + 0x65,0x38,0x65,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, + 0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, + 0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30, + 0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, + 0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66, + 0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63, + 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74, + 0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65, + 0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, + 0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f, + 0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, + 0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78, + 0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70, + 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73, + 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72, + 0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20, + 0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30, + 0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63, + 0x32,0x31,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75, + 0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62, + 0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, + 0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30, + 0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74, + 0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d, + 0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53, + 0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a, + 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09, + 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09, + 0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23, + 0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29, + 0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31, + 0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09, + 0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09, + 0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28, - 0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f, - 0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x34,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e, - 0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28, - 0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62, - 0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46, - 0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f, - 0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b, - 0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65, - 0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b, - 0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x3d, - 0x69,0x6d,0x75,0x6c,0x5f,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3b,0x0a,0x69,0x66,0x28,0x72,0x3d,0x3d,0x31,0x29, - 0x0a,0x7b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f, - 0x50,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46, - 0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52, - 0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d, - 0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x72,0x29,0x5b,0x30, - 0x5d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3d,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x72,0x29,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a, - 0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e, - 0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x35,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d, - 0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x29,0x7c,0x28,0x33,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d, - 0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b, - 0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69, - 0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x2a,0x28, - 0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77, - 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34, - 0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, - 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x7c,0x28,0x33,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69, - 0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64, - 0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f, - 0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28, - 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d, - 0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69, - 0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72, - 0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, - 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f, - 0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52, - 0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x7c,0x28,0x37,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64, - 0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46, - 0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a, - 0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d, - 0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3e,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69, - 0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b, - 0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c, - 0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, - 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46, - 0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x38,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44, - 0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29, - 0x3d,0x28,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x3f,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3a,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x29,0x7c,0x6e,0x75, - 0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x31,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x73,0x72,0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74, - 0x29,0x3c,0x3c,0x28,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e, - 0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73, - 0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a, - 0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46, - 0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f, - 0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e, - 0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c, - 0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f, - 0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b, - 0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75, - 0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73, - 0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x7c,0x28,0x28,0x73,0x72,0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x28,0x53, - 0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, - 0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f, - 0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72, - 0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c, - 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28, - 0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46, - 0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f, - 0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4e, - 0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d, - 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c, - 0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32, - 0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73, - 0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, - 0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29, - 0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46, - 0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x36, - 0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x33,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66, - 0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c, - 0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29, - 0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5f,0x66,0x73,0x63,0x61,0x6c,0x5f,0x72,0x3d,0x69,0x6d,0x6d, - 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f, - 0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x30,0x3b, - 0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3d,0x30,0x78,0x38,0x30,0x46,0x30,0x30,0x30,0x30,0x30, - 0x55,0x4c,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64, - 0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a, - 0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c, - 0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x73,0x72,0x63,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e, - 0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x28,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x2b,0x31,0x29,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54, - 0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x32,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28, - 0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77, - 0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x31,0x3a,0x32,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d, - 0x28,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x2b,0x52,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c, - 0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x35,0x3c, - 0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64, - 0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d, - 0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b, - 0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74, - 0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f, - 0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d, - 0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d, - 0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69, - 0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x28,0x28,0x64,0x73,0x74,0x20,0x25,0x20,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29, - 0x2b,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x43,0x6f,0x75,0x6e,0x74,0x46,0x6c,0x74,0x29,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c, - 0x28,0x31,0x34,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f, - 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63, - 0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x29,0x7c,0x28,0x39,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x3d, - 0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x2b,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f, - 0x6e,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x7c,0x28,0x31,0x55, - 0x3c,0x3c,0x63,0x73,0x68,0x69,0x66,0x74,0x29,0x3b,0x0a,0x69,0x66,0x28,0x63,0x73,0x68,0x69,0x66,0x74,0x3e,0x30,0x29,0x0a,0x69,0x6d,0x6d,0x20,0x26,0x3d,0x20,0x7e, - 0x28,0x31,0x55,0x3c,0x3c,0x28,0x63,0x73,0x68,0x69,0x66,0x74,0x2d,0x31,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x49, - 0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f, - 0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x69,0x6d,0x6d,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d, - 0x3d,0x63,0x73,0x68,0x69,0x66,0x74,0x7c,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65, - 0x74,0x5f,0x73,0x6c,0x6f,0x74,0x29,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x3d,0x32,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73, - 0x65,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x7d,0x0a,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61, - 0x72,0x67,0x65,0x74,0x5f,0x73,0x6c,0x6f,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, - 0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48, - 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44, - 0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x33, - 0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x36,0x33,0x29,0x3c,0x3c,0x49, - 0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b, - 0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a, - 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x29,0x0a,0x7b, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e, - 0x34,0x29,0x3e,0x3d,0x53,0x74,0x6f,0x72,0x65,0x4c,0x33,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x29,0x3f,0x33,0x3a,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20, - 0x34,0x29,0x3f,0x31,0x3a,0x32,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x28,0x64,0x73,0x74,0x3c,0x3c,0x44,0x53,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, - 0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x7c,0x28,0x31,0x3c,0x3c,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x29,0x7c,0x28,0x31,0x30,0x3c,0x3c,0x4f,0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c, - 0x3d,0x69,0x6d,0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6d,0x6d,0x5f,0x69, - 0x6e,0x64,0x65,0x78,0x3c,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x29,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x69,0x6d, - 0x6d,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x2b,0x5d,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x30,0x78,0x46,0x43,0x31,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c, - 0x28,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x31,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x31,0x3a,0x28,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f, - 0x6e,0x3d,0x3d,0x32,0x29,0x3f,0x4c,0x4f,0x43,0x5f,0x4c,0x32,0x3a,0x4c,0x4f,0x43,0x5f,0x4c,0x33,0x29,0x29,0x3c,0x3c,0x32,0x31,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65, - 0x0a,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3d,0x49,0x4e,0x53,0x54,0x5f,0x4e,0x4f,0x50,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f, - 0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x74, - 0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54, - 0x4f,0x52,0x45,0x3b,0x0a,0x2a,0x28,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x7c,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3b,0x0a,0x7d,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x32,0x30,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x63,0x6f,0x6d,0x70, - 0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a, - 0x29,0x28,0x52,0x2b,0x28,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53,0x49,0x5a,0x45, - 0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6c, - 0x6f,0x61,0x64,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x64,0x73,0x74, - 0x5f,0x62,0x75,0x66,0x2c,0x73,0x69,0x7a,0x65,0x5f,0x74,0x20,0x4e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69, - 0x64,0x2a,0x20,0x73,0x72,0x63,0x5f,0x62,0x75,0x66,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63, - 0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x65,0x70,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29, - 0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73, - 0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x73,0x72,0x63,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x73,0x72,0x63,0x5f,0x62,0x75,0x66,0x29,0x2b,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30, - 0x29,0x2a,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x2a,0x4e,0x2b,0x69,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20, - 0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x73,0x74,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29, - 0x64,0x73,0x74,0x5f,0x62,0x75,0x66,0x29,0x2b,0x69,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x69,0x3c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74, - 0x36,0x34,0x5f,0x74,0x29,0x2a,0x4e,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28, - 0x64,0x73,0x74,0x29,0x3d,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x72,0x63,0x29,0x3b, - 0x0a,0x73,0x72,0x63,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x64,0x73,0x74,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a,0x69,0x2b,0x3d,0x73,0x74,0x65,0x70,0x3b,0x0a, - 0x7d,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f,0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x69,0x6e,0x74,0x20,0x76, - 0x61,0x6c,0x75,0x65,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f, - 0x72,0x4d,0x61,0x73,0x6b,0x29,0x0a,0x7b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x3d,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x5f,0x72,0x74,0x6e,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x78,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67, - 0x28,0x74,0x29,0x3b,0x0a,0x78,0x20,0x26,0x3d,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x78,0x7c,0x3d,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x72,0x65, - 0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x78,0x29,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x66,0x6d,0x61,0x5f, - 0x73,0x6f,0x66,0x74,0x28,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x61,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x63,0x2c, - 0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x72,0x6f,0x75, - 0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x6d,0x61,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29, - 0x3b,0x0a,0x69,0x66,0x28,0x28,0x61,0x3d,0x3d,0x30,0x2e,0x30,0x29,0x7c,0x7c,0x28,0x62,0x3d,0x3d,0x30,0x2e,0x30,0x29,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, - 0x63,0x3b,0x0a,0x69,0x66,0x28,0x62,0x3d,0x3d,0x31,0x2e,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x63,0x3d,0x3d,0x30,0x2e,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72, - 0x6e,0x20,0x61,0x3b,0x0a,0x69,0x66,0x28,0x63,0x3d,0x3d,0x2d,0x61,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20, - 0x6d,0x69,0x6e,0x75,0x73,0x5f,0x7a,0x65,0x72,0x6f,0x3d,0x31,0x55,0x4c,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x72,0x6f,0x75,0x6e, - 0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x29,0x3f,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x6d,0x69,0x6e,0x75,0x73,0x5f,0x7a,0x65, - 0x72,0x6f,0x29,0x3a,0x30,0x2e,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74, - 0x69,0x73,0x73,0x61,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x35,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e, - 0x74,0x69,0x73,0x73,0x61,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x31,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x31,0x3c,0x3c,0x65,0x78,0x70,0x6f,0x6e,0x65, - 0x6e,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2d,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x61,0x32,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x61,0x29, - 0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x62,0x32,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x62,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x32, - 0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70, - 0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61,0x3d,0x28,0x61,0x32,0x2e,0x79,0x3e,0x3e,0x32,0x30,0x29,0x26,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b, - 0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x62,0x3d,0x28,0x62,0x32,0x2e, - 0x79,0x3e,0x3e,0x32,0x30,0x29,0x26,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x3d,0x28,0x63,0x32,0x2e,0x79,0x3e,0x3e,0x32,0x30,0x29,0x26,0x65,0x78,0x70,0x6f,0x6e, - 0x65,0x6e,0x74,0x5f,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x69,0x66,0x28,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x7c, - 0x7c,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x62,0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x7c,0x7c,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63, - 0x3d,0x3d,0x32,0x30,0x34,0x37,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x66,0x3d,0x32,0x30, - 0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69,0x6e,0x66,0x29,0x3b, - 0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x61,0x3d,0x61,0x32,0x2e,0x79,0x3e,0x3e,0x33, - 0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x62,0x3d,0x62,0x32,0x2e,0x79,0x3e,0x3e,0x33, - 0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x63,0x3d,0x63,0x32,0x2e,0x79,0x3e,0x3e,0x33, - 0x31,0x3b,0x0a,0x61,0x32,0x2e,0x79,0x3d,0x28,0x61,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29,0x29,0x7c,0x28,0x31,0x55,0x3c, - 0x3c,0x32,0x30,0x29,0x3b,0x0a,0x62,0x32,0x2e,0x79,0x3d,0x28,0x62,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29,0x29,0x7c,0x28, - 0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x3b,0x0a,0x63,0x32,0x2e,0x79,0x3d,0x28,0x63,0x32,0x2e,0x79,0x26,0x28,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x2d,0x31,0x29, - 0x29,0x7c,0x28,0x31,0x55,0x3c,0x3c,0x32,0x30,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x61,0x3d, - 0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f, - 0x62,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x62,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73, - 0x61,0x5f,0x63,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x63,0x32,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6d,0x75,0x6c,0x5f,0x72, - 0x65,0x73,0x75,0x6c,0x74,0x5b,0x32,0x5d,0x3b,0x0a,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61, - 0x5f,0x61,0x2a,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x62,0x3b,0x0a,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x75,0x6c, - 0x5f,0x68,0x69,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x61,0x2c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x62,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31, - 0x5d,0x3e,0x3e,0x34,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73, - 0x75,0x6c,0x74,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x61,0x2b,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x62,0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f, - 0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x2d,0x31,0x30,0x32,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c, - 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x61,0x5e,0x73,0x69,0x67,0x6e,0x5f,0x62,0x3b,0x0a,0x69,0x66,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65, - 0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3e,0x3d,0x32,0x30,0x34,0x37,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e, - 0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x3d,0x28,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x2d,0x28,0x72,0x6f,0x75,0x6e, - 0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x26,0x31,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69, - 0x6e,0x66,0x5f,0x72,0x6e,0x64,0x29,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x32, - 0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x5b,0x32,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x65,0x78,0x70,0x6f,0x6e, - 0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f, - 0x72,0x65,0x73,0x75,0x6c,0x74,0x3e,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73, - 0x68,0x69,0x66,0x74,0x3d,0x32,0x33,0x2d,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75, - 0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x3b,0x0a,0x66,0x6d,0x61,0x5f, - 0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29, - 0x7c,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x29,0x29,0x3b,0x0a,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x32,0x3d,0x28,0x31,0x32,0x37,0x2d,0x35,0x32,0x29,0x2b,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28, - 0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x2d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3b, - 0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x36,0x34,0x29,0x0a, - 0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3c,0x3c,0x28,0x73,0x68,0x69,0x66, - 0x74,0x32,0x2d,0x36,0x34,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63, - 0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x73,0x68,0x69,0x66,0x74,0x32,0x3f,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f, - 0x63,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3a,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x74,0x5b, - 0x30,0x5d,0x3d,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3c,0x2d,0x35,0x32,0x29,0x3f,0x30,0x3a,0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3e,0x3e,0x28, - 0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x28,0x74,0x5b,0x30,0x5d,0x3d,0x3d,0x30,0x29,0x26, - 0x26,0x28,0x63,0x21,0x3d,0x30,0x2e,0x30,0x29,0x29,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x31,0x3b,0x0a,0x7d,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d, - 0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a, - 0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x74,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x63,0x3c,0x3c, - 0x31,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x32,0x3d,0x28,0x31,0x32,0x37,0x2d,0x31,0x30,0x34,0x2d,0x65,0x78,0x70,0x5f, - 0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x29,0x2b,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x6d, - 0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32, - 0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b, - 0x30,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72, - 0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3f,0x28,0x6d,0x75,0x6c,0x5f,0x72, - 0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3a,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73, - 0x65,0x0a,0x7b,0x0a,0x73,0x68,0x69,0x66,0x74,0x32,0x3d,0x2d,0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x32,0x3e,0x3d,0x36, - 0x34,0x29,0x0a,0x7b,0x0a,0x73,0x68,0x69,0x66,0x74,0x32,0x2d,0x3d,0x36,0x34,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x28, - 0x73,0x68,0x69,0x66,0x74,0x32,0x3c,0x36,0x34,0x29,0x3f,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74, - 0x32,0x29,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65, - 0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x31,0x3b,0x0a,0x7d,0x0a,0x65, - 0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b, - 0x30,0x5d,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x7c,0x28,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x28,0x36,0x34,0x2d, - 0x73,0x68,0x69,0x66,0x74,0x32,0x29,0x29,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75, - 0x6c,0x74,0x5b,0x31,0x5d,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74,0x32,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f, - 0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x63,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x69, - 0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x69,0x66,0x28,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c, - 0x74,0x3d,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x63,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x2b,0x3d,0x74,0x5b,0x30,0x5d, - 0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x74,0x5b,0x31,0x5d,0x2b,0x28,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75, - 0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x74,0x5b,0x30,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x29,0x3b,0x0a,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e, - 0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x74,0x5b,0x31,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x73,0x69,0x67,0x6e,0x5f, - 0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x65,0x6c, - 0x73,0x65,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x6f,0x72,0x72,0x6f,0x77,0x3d,0x28,0x66,0x6d,0x61,0x5f, - 0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3c,0x74,0x5b,0x30,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b, - 0x30,0x5d,0x2d,0x3d,0x74,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x62,0x6f,0x72,0x72,0x6f,0x77,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,0x5f,0x73,0x69,0x67,0x6e,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31, - 0x5d,0x3c,0x74,0x5b,0x31,0x5d,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2d,0x3d,0x74,0x5b,0x31,0x5d, - 0x3b,0x0a,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x73,0x69,0x67,0x6e,0x5f,0x6d,0x75,0x6c,0x5f,0x72,0x65,0x73,0x75,0x6c, - 0x74,0x5e,0x63,0x68,0x61,0x6e,0x67,0x65,0x5f,0x73,0x69,0x67,0x6e,0x3b,0x0a,0x69,0x66,0x28,0x63,0x68,0x61,0x6e,0x67,0x65,0x5f,0x73,0x69,0x67,0x6e,0x29,0x0a,0x7b, - 0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x2d,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65, - 0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x7e,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73, - 0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c, - 0x74,0x5b,0x30,0x5d,0x3f,0x30,0x3a,0x31,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x3d,0x30,0x29, - 0x0a,0x7b,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30, - 0x2e,0x30,0x3b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2d,0x3d,0x36,0x34,0x3b,0x0a,0x66,0x6d,0x61, - 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65, - 0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65, - 0x78,0x3d,0x63,0x6c,0x7a,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x64,0x65,0x78,0x29,0x0a, - 0x7b,0x0a,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2d,0x3d,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x66,0x6d, - 0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3c,0x3c,0x69,0x6e,0x64,0x65, - 0x78,0x29,0x7c,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x30,0x5d,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x69,0x6e,0x64,0x65,0x78,0x29,0x29,0x3b,0x0a, - 0x7d,0x0a,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x31,0x31,0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x63,0x6f, - 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x75,0x70,0x3d,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c, - 0x74,0x5b,0x30,0x5d,0x7c,0x7c,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x26,0x28,0x28,0x31,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29, - 0x2d,0x31,0x29,0x29,0x29,0x3f,0x31,0x3a,0x30,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x20,0x3e,0x3e,0x3d,0x20,0x73,0x68,0x69, - 0x66,0x74,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x20,0x26,0x3d,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x5f,0x6d,0x61, - 0x73,0x6b,0x3b,0x0a,0x69,0x66,0x28,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5f,0x6d,0x6f,0x64,0x65,0x2b,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65, - 0x73,0x75,0x6c,0x74,0x3d,0x3d,0x32,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x2b,0x3d,0x72,0x6f,0x75,0x6e,0x64,0x5f, - 0x75,0x70,0x3b,0x0a,0x69,0x66,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x3d,0x28,0x31,0x55,0x4c,0x3c,0x3c,0x6d,0x61,0x6e,0x74, - 0x69,0x73,0x73,0x61,0x5f,0x73,0x69,0x7a,0x65,0x29,0x29,0x0a,0x7b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x2b, - 0x2b,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65, - 0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x5f,0x66,0x6d,0x61, - 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x2b,0x65,0x78,0x70,0x5f,0x63,0x6f,0x72,0x72,0x65,0x63,0x74,0x69,0x6f,0x6e,0x29,0x3c,0x3c,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73, - 0x61,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x0a,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, - 0x29,0x28,0x73,0x69,0x67,0x6e,0x5f,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3c,0x3c,0x36,0x33,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61, - 0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x66,0x6d,0x61,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c, - 0x65,0x20,0x64,0x69,0x76,0x5f,0x72,0x6e,0x64,0x28,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x61,0x2c,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x2c,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72,0x63,0x29,0x0a,0x7b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x79,0x30,0x3d,0x31,0x2e,0x30,0x2f,0x62,0x3b,0x0a,0x63,0x6f, - 0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x30,0x3d,0x61,0x2a,0x79,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x20,0x74,0x31,0x3d,0x66,0x6d,0x61,0x28,0x2d,0x62,0x2c,0x74,0x30,0x2c,0x61,0x29,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d, - 0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66,0x74,0x28,0x79,0x30,0x2c,0x74,0x31,0x2c,0x74,0x30,0x2c,0x66,0x70,0x72,0x63,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x66,0x3d,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x3d,0x69,0x6e,0x66,0x2d,0x28,0x66,0x70,0x72,0x63,0x26,0x31,0x29,0x3b,0x0a,0x69,0x66,0x28, - 0x28,0x28,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x29,0x3e,0x3e,0x35,0x32,0x29,0x26,0x32,0x30,0x34,0x37,0x29,0x3d,0x3d,0x32, - 0x30,0x34,0x37,0x29,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x69,0x6e,0x66,0x5f,0x72,0x6e,0x64,0x29,0x3b,0x0a, - 0x69,0x66,0x28,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x29,0x3d,0x3d,0x69,0x6e,0x66,0x29,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x3b,0x0a,0x72, - 0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x61,0x3d,0x3d,0x62,0x29,0x3f,0x31,0x2e,0x30,0x3a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x64,0x6f,0x75,0x62,0x6c, - 0x65,0x20,0x73,0x71,0x72,0x74,0x5f,0x72,0x6e,0x64,0x28,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72, - 0x63,0x29,0x0a,0x7b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x79,0x30,0x3d,0x72,0x73,0x71,0x72,0x74,0x28,0x78,0x29,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20, - 0x74,0x30,0x3d,0x79,0x30,0x2a,0x78,0x3b,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x74,0x31,0x3d,0x79,0x30,0x2a,0x2d,0x30,0x2e,0x35,0x3b,0x0a,0x74,0x31,0x3d,0x66, - 0x6d,0x61,0x28,0x74,0x31,0x2c,0x74,0x30,0x2c,0x30,0x2e,0x35,0x29,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65, - 0x20,0x79,0x31,0x5f,0x78,0x3d,0x66,0x6d,0x61,0x28,0x74,0x30,0x2c,0x74,0x31,0x2c,0x74,0x30,0x29,0x3b,0x09,0x0a,0x79,0x30,0x20,0x2a,0x3d,0x20,0x30,0x2e,0x35,0x3b, - 0x0a,0x79,0x30,0x3d,0x66,0x6d,0x61,0x28,0x79,0x30,0x2c,0x74,0x31,0x2c,0x79,0x30,0x29,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x74,0x31,0x3d,0x66,0x6d,0x61,0x28,0x2d, - 0x79,0x31,0x5f,0x78,0x2c,0x79,0x31,0x5f,0x78,0x2c,0x78,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d, - 0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66,0x74,0x28,0x74,0x31,0x2c,0x79,0x30,0x2c,0x79,0x31,0x5f,0x78,0x2c,0x66,0x70,0x72,0x63,0x29,0x3b,0x09,0x09,0x0a,0x69,0x66,0x28, - 0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x20,0x26,0x78,0x29,0x3d,0x3d,0x28,0x32,0x30,0x34,0x37,0x55,0x4c,0x3c,0x3c,0x35,0x32,0x29,0x29, - 0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x78,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74, - 0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x6e,0x65,0x72,0x5f,0x6c,0x6f,0x6f,0x70,0x28,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, - 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x2c,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x73, - 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67, - 0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67, - 0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, - 0x20,0x52,0x2c,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2c,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x20,0x66,0x70,0x72,0x63,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65, - 0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e, - 0x74,0x4d,0x61,0x73,0x6b,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61, - 0x73,0x6b,0x0a,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x32,0x3d,0x73,0x75,0x62,0x3e,0x3e,0x31, - 0x3b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3d,0x66,0x70,0x72, - 0x63,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x69,0x70,0x3d,0x30,0x3b,0x20,0x69,0x70,0x3c,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d, - 0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3d,0x69,0x70,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x3d,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x70,0x5d,0x3b,0x0a,0x63,0x6f, - 0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4e, - 0x55,0x4d,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41, - 0x53,0x48,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74, - 0x73,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4e,0x55,0x4d,0x5f,0x46,0x50,0x5f,0x49,0x4e,0x53,0x54,0x53,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x28,0x57, - 0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f, - 0x74,0x20,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3d,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x2d,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69, - 0x6e,0x73,0x74,0x73,0x3b,0x0a,0x69,0x66,0x28,0x73,0x75,0x62,0x3c,0x3d,0x6e,0x75,0x6d,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x75,0x62,0x2d,0x6e,0x75,0x6d,0x5f,0x66, - 0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f,0x66,0x70,0x3d,0x69,0x6e,0x73,0x74,0x5f,0x6f, - 0x66,0x66,0x73,0x65,0x74,0x3c,0x6e,0x75,0x6d,0x5f,0x66,0x70,0x5f,0x69,0x6e,0x73,0x74,0x73,0x3b,0x0a,0x69,0x6e,0x73,0x74,0x3d,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65, - 0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5b,0x69,0x70,0x2b,0x28,0x69,0x73,0x5f,0x66,0x70,0x3f,0x73,0x75,0x62,0x32,0x3a,0x69,0x6e,0x73,0x74,0x5f,0x6f,0x66, - 0x66,0x73,0x65,0x74,0x29,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4f, - 0x50,0x43,0x4f,0x44,0x45,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x31,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x4c,0x4f,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x31,0x3b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x69,0x73, - 0x5f,0x66,0x70,0x3f,0x34,0x3a,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65, - 0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x69,0x73,0x5f,0x66,0x70,0x3f,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3a,0x30,0x3b,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65, - 0x74,0x3d,0x69,0x73,0x5f,0x66,0x70,0x3f,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3a,0x30,0x3b, - 0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x44,0x53,0x54,0x5f, - 0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x37,0x3b,0x0a,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x6f, - 0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3c,0x3c,0x72,0x65,0x67,0x5f,0x73,0x69,0x7a,0x65,0x5f,0x73,0x68,0x69,0x66, - 0x74,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x53, - 0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x37,0x3b,0x0a,0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x73,0x72,0x63,0x5f,0x6f,0x66, - 0x66,0x73,0x65,0x74,0x3c,0x3c,0x33,0x29,0x2b,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3f,0x30,0x3a,0x72,0x65,0x67,0x5f,0x62,0x61,0x73,0x65,0x5f,0x73,0x72, - 0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x64,0x73,0x74, - 0x5f,0x70,0x74,0x72,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61, - 0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b,0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f, - 0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75, - 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b, - 0x73,0x72,0x63,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x5f, - 0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x49,0x4d,0x4d,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x26,0x32,0x35,0x35,0x3b,0x0a,0x5f, - 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x70,0x74,0x72,0x3d,0x69, - 0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2b,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x73,0x74,0x3d, - 0x2a,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x73,0x72,0x63,0x3d,0x2a,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3b, - 0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6d,0x6d,0x3b,0x0a,0x69,0x6d,0x6d,0x2e,0x78,0x3d,0x69,0x6d,0x6d,0x5f,0x70,0x74,0x72,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6d, - 0x6d,0x2e,0x79,0x3d,0x69,0x6d,0x6d,0x5f,0x70,0x74,0x72,0x5b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x7b,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x3e,0x3e, - 0x32,0x31,0x29,0x26,0x33,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x30,0x78,0x46, - 0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x29,0x2d,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f, - 0x6f,0x6c,0x20,0x69,0x73,0x5f,0x72,0x65,0x61,0x64,0x3d,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x21,0x3d,0x31,0x30,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f, - 0x74,0x20,0x61,0x64,0x64,0x72,0x3d,0x69,0x73,0x5f,0x72,0x65,0x61,0x64,0x3f,0x28,0x28,0x6c,0x6f,0x63,0x5f,0x73,0x68,0x69,0x66,0x74,0x3d,0x3d,0x4c,0x4f,0x43,0x5f, - 0x4c,0x33,0x29,0x3f,0x30,0x3a,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x3a,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x29,0x28,0x64,0x73,0x74,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x2b,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a, - 0x61,0x64,0x64,0x72,0x20,0x26,0x3d,0x20,0x6d,0x61,0x73,0x6b,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, - 0x20,0x70,0x74,0x72,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x2b,0x61,0x64,0x64,0x72,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x73,0x5f,0x72,0x65,0x61,0x64,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x3d,0x2a,0x70, - 0x74,0x72,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x70,0x74,0x72,0x3d,0x73,0x72,0x63,0x3b,0x0a,0x67,0x6f,0x74,0x6f,0x20,0x65,0x78,0x65,0x63, - 0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65,0x6e,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43, - 0x5f,0x49,0x53,0x5f,0x49,0x4d,0x4d,0x33,0x32,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, - 0x29,0x28,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x29,0x29,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x3d,0x33,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41, - 0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29, - 0x28,0x2d,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x30,0x29, - 0x20,0x64,0x73,0x74,0x2b,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x3e,0x3e,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54, - 0x29,0x26,0x33,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x32,0x29,0x20,0x64,0x73,0x74,0x2b,0x3d,0x73,0x72,0x63,0x3c,0x3c,0x73,0x68,0x69,0x66, - 0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6d,0x6d,0x36,0x34,0x3d,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36, - 0x34,0x5f,0x74,0x2a,0x29,0x20,0x26,0x69,0x6d,0x6d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x52,0x43,0x5f,0x49,0x53,0x5f, - 0x49,0x4d,0x4d,0x36,0x34,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x3d,0x69,0x6d,0x6d,0x36,0x34,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x3d,0x3d,0x32,0x29,0x20,0x64,0x73,0x74,0x20,0x2a,0x3d,0x20,0x73,0x72,0x63,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x33, - 0x29,0x20,0x64,0x73,0x74,0x20,0x5e,0x3d,0x20,0x73,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d, - 0x31,0x32,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x29,0x20,0x73,0x72,0x63,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28, - 0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x72,0x74,0x6e,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x73,0x72,0x63, - 0x3e,0x3e,0x28,0x28,0x73,0x75,0x62,0x26,0x31,0x29,0x2a,0x33,0x32,0x29,0x29,0x29,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e, - 0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x20,0x73,0x72,0x63,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30, - 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f, - 0x6d,0x75,0x6c,0x3d,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x53,0x48,0x49,0x46,0x54,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x29,0x29,0x21,0x3d,0x30,0x3b, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x61,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x64,0x73,0x74,0x29,0x3b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x20,0x62,0x3d,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x73,0x72,0x63,0x29,0x3b,0x0a,0x64, - 0x73,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x66,0x6d,0x61,0x5f,0x73,0x6f,0x66,0x74,0x28,0x61,0x2c,0x69,0x73,0x5f,0x6d,0x75,0x6c,0x3f,0x62,0x3a, - 0x31,0x2e,0x30,0x2c,0x69,0x73,0x5f,0x6d,0x75,0x6c,0x3f,0x30,0x2e,0x30,0x3a,0x62,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x39,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x2b,0x3d,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69, - 0x6d,0x6d,0x2e,0x78,0x29,0x3b,0x0a,0x69,0x66,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x26,0x28,0x43,0x6f,0x6e,0x64, - 0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61,0x73,0x6b,0x3c,0x3c,0x28,0x69,0x6d,0x6d,0x2e,0x79,0x26,0x33,0x31,0x29,0x29,0x29,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6d, - 0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3d,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x29,0x28,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28,0x69,0x6d,0x6d,0x2e,0x79,0x29,0x3e,0x3e,0x35,0x29,0x2d,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74, - 0x73,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x37,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x31,0x3d,0x73,0x72,0x63,0x26,0x36,0x33,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x20,0x3e,0x20,0x30,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20, - 0x73,0x68,0x69,0x66,0x74,0x32,0x3d,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x69,0x73,0x5f, - 0x72,0x6f,0x6c,0x3d,0x28,0x69,0x6e,0x73,0x74,0x26,0x28,0x31,0x3c,0x3c,0x4e,0x45,0x47,0x41,0x54,0x49,0x56,0x45,0x5f,0x53,0x52,0x43,0x5f,0x4f,0x46,0x46,0x53,0x45, - 0x54,0x29,0x29,0x3b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x3e,0x3e,0x28,0x69,0x73,0x5f,0x72,0x6f,0x6c,0x3f,0x73,0x68,0x69,0x66,0x74,0x32,0x3a,0x73,0x68, - 0x69,0x66,0x74,0x31,0x29,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x28,0x69,0x73,0x5f,0x72,0x6f,0x6c,0x3f,0x73,0x68,0x69,0x66,0x74,0x31,0x3a,0x73,0x68,0x69,0x66, - 0x74,0x32,0x29,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x64,0x73,0x74,0x3d,0x28,0x64,0x73,0x74,0x3e,0x3e,0x73,0x68,0x69,0x66,0x74,0x31,0x29,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x31,0x29,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x34,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x73,0x71, - 0x72,0x74,0x5f,0x72,0x6e,0x64,0x28,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x64,0x73,0x74,0x29,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b,0x0a,0x7d,0x0a, - 0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x36,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x6d,0x75,0x6c,0x5f,0x68,0x69,0x28, - 0x64,0x73,0x74,0x2c,0x73,0x72,0x63,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x34,0x29,0x0a,0x7b, - 0x0a,0x64,0x73,0x74,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x6d,0x75,0x6c,0x5f,0x68,0x69,0x28,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29, - 0x28,0x64,0x73,0x74,0x29,0x2c,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x73,0x72,0x63,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69, - 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x31,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x2a,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69, - 0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x52,0x29,0x2b,0x28, - 0x64,0x73,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x5e,0x38,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3d,0x3d,0x38,0x29,0x0a,0x7b,0x0a,0x2a,0x73,0x72,0x63,0x5f,0x70,0x74,0x72,0x3d,0x64,0x73,0x74,0x3b,0x0a,0x64,0x73,0x74,0x3d,0x73,0x72,0x63,0x3b,0x0a,0x7d,0x0a, - 0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x31,0x35,0x29,0x0a,0x7b,0x0a,0x73,0x72,0x63,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f, - 0x6e,0x67,0x28,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x5f,0x72,0x74,0x6e,0x28,0x28,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x28, - 0x73,0x72,0x63,0x3e,0x3e,0x28,0x28,0x73,0x75,0x62,0x26,0x31,0x29,0x2a,0x33,0x32,0x29,0x29,0x29,0x29,0x3b,0x0a,0x73,0x72,0x63,0x20,0x26,0x3d,0x20,0x64,0x79,0x6e, - 0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x73,0x72,0x63,0x7c,0x3d,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74, - 0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x64,0x73,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x64,0x69,0x76,0x5f,0x72,0x6e,0x64,0x28,0x61,0x73,0x5f,0x64,0x6f, - 0x75,0x62,0x6c,0x65,0x28,0x64,0x73,0x74,0x29,0x2c,0x61,0x73,0x5f,0x64,0x6f,0x75,0x62,0x6c,0x65,0x28,0x73,0x72,0x63,0x29,0x2c,0x66,0x70,0x72,0x63,0x29,0x29,0x3b, - 0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x3d,0x35,0x29,0x0a,0x7b,0x0a,0x64,0x73,0x74,0x3d,0x28,0x75,0x69,0x6e, - 0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x2d,0x28,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x64,0x73,0x74,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20, - 0x69,0x66,0x28,0x52,0x4f,0x55,0x4e,0x44,0x49,0x4e,0x47,0x5f,0x4d,0x4f,0x44,0x45,0x3c,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b,0x49,0x4d, - 0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3d,0x28,0x28,0x73,0x72,0x63,0x3e,0x3e,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73, - 0x65,0x74,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x69,0x6d,0x6d,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x29,0x26,0x33,0x3b,0x0a,0x67, - 0x6f,0x74,0x6f,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65,0x6e,0x64,0x3b,0x0a,0x7d,0x0a,0x2a,0x64,0x73,0x74,0x5f,0x70,0x74,0x72,0x3d,0x64,0x73, - 0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6f,0x6e,0x5f,0x65,0x6e,0x64,0x3a,0x0a,0x7b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28, - 0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x70,0x3d,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66, - 0x5b,0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x5d,0x3b,0x0a,0x66,0x70,0x72,0x63,0x3d,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x5b, - 0x49,0x4d,0x4d,0x5f,0x49,0x4e,0x44,0x45,0x58,0x5f,0x43,0x4f,0x55,0x4e,0x54,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x70,0x2b,0x3d,0x6e,0x75,0x6d,0x5f,0x69,0x6e,0x73,0x74, - 0x73,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x66,0x70,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x23,0x69,0x66,0x20,0x57,0x4f,0x52,0x4b, - 0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x20,0x3d,0x3d,0x20,0x31,0x36,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f, - 0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29, - 0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f, - 0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x31,0x36,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65, - 0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x5f,0x76,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f, - 0x69,0x64,0x2a,0x20,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x72,0x6f,0x75, - 0x6e,0x64,0x69,0x6e,0x67,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x73, - 0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x76,0x6f,0x69,0x64,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x5f,0x70,0x74, - 0x72,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e, - 0x75,0x6d,0x5f,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x69,0x72,0x73,0x74,0x2c,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x76, - 0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5b,0x28,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x32,0x29, - 0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x6c,0x6f,0x61,0x64,0x5f,0x62,0x75,0x66,0x66,0x65,0x72,0x28, - 0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x2c,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73, - 0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x2c,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74, - 0x65,0x73,0x29,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45, - 0x29,0x3b,0x0a,0x65,0x6e,0x75,0x6d,0x20,0x7b,0x20,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x3d,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52, - 0x5f,0x48,0x41,0x53,0x48,0x3d,0x3d,0x31,0x36,0x29,0x3f,0x31,0x36,0x3a,0x38,0x20,0x7d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36, - 0x34,0x5f,0x74,0x2a,0x20,0x52,0x3d,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x2b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61, - 0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x2a,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49,0x5a,0x45, - 0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c, - 0x65,0x2a,0x20,0x46,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x38,0x29,0x3b,0x0a,0x5f,0x5f,0x6c, - 0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x45,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29, - 0x28,0x52,0x2b,0x31,0x36,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x20,0x69,0x64,0x78,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x75,0x62,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x20,0x25, - 0x20,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x61,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61, - 0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x6d,0x78,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b, - 0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74, - 0x65,0x72,0x73,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b, - 0x32,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64, - 0x52,0x65,0x67,0x30,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63, - 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73, - 0x26,0x30,0x78,0x66,0x66,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a, - 0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x31,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28, - 0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67, - 0x69,0x73,0x74,0x65,0x72,0x73,0x3e,0x3e,0x38,0x29,0x26,0x30,0x78,0x66,0x66,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x32,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x28, - 0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3e,0x3e,0x31,0x36,0x29,0x26,0x30,0x78,0x66,0x66,0x29,0x29,0x3b,0x0a,0x5f,0x5f, - 0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x33,0x3d,0x28, - 0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x38,0x5f,0x74,0x2a,0x29,0x52,0x29,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3e,0x3e,0x32,0x34,0x29,0x29, - 0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28, - 0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x33,0x5d,0x3b,0x0a,0x5f, - 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x3d,0x28, - 0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x64,0x61,0x74,0x61,0x73,0x65,0x74, - 0x5f,0x70,0x74,0x72,0x29,0x2b,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x4f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x36,0x34,0x2b,0x28,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x26,0x31,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x72,0x65, - 0x67,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x31,0x39,0x32,0x2b,0x28,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x26,0x31,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x65,0x4d, - 0x61,0x73,0x6b,0x3d,0x52,0x2b,0x31,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d, - 0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x32, - 0x30,0x29,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x72,0x63,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x29,0x5b,0x69,0x64,0x78,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33, - 0x32,0x5f,0x74,0x20,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x3d,0x66,0x69,0x72,0x73,0x74,0x3f,0x6d,0x78,0x3a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x20,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x3d,0x66,0x69,0x72,0x73,0x74,0x3f,0x6d,0x61,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, - 0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x38,0x5f,0x74,0x2a,0x29,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74, - 0x29,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x33,0x2b,0x36,0x34,0x29,0x3b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3d,0x28,0x73,0x75,0x62,0x3c,0x34,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c, - 0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x66,0x65,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x28,0x46,0x2b,0x73,0x75,0x62,0x2a,0x32,0x29,0x3a,0x28,0x45, - 0x2b,0x28,0x73,0x75,0x62,0x2d,0x34,0x29,0x2a,0x32,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x66,0x3d,0x46, - 0x2b,0x73,0x75,0x62,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x65,0x3d,0x45,0x2b,0x73,0x75,0x62,0x3b,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x28,0x75, - 0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x2d,0x31,0x29,0x3a,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b, - 0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x31,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70, - 0x3f,0x30,0x3a,0x65,0x4d,0x61,0x73,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x72,0x4d,0x61, - 0x73,0x6b,0x32,0x3d,0x66,0x5f,0x67,0x72,0x6f,0x75,0x70,0x3f,0x30,0x3a,0x65,0x4d,0x61,0x73,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x78,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x3d,0x28,0x73,0x75,0x62,0x26,0x31,0x29,0x3f,0x65,0x4d,0x61, - 0x73,0x6b,0x5b,0x31,0x5d,0x3a,0x65,0x4d,0x61,0x73,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74, - 0x2a,0x20,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b, - 0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29, - 0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c, - 0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32, - 0x5f,0x74,0x2a,0x29,0x28,0x52,0x2b,0x28,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x49,0x4d,0x4d,0x5f,0x42,0x55,0x46,0x5f,0x53, - 0x49,0x5a,0x45,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x28,0x31,0x3c,0x3c,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53, - 0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x2d,0x31,0x29,0x3c,0x3c,0x28,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29, - 0x2f,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x2a,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x3d,0x33,0x3c,0x3c,0x28,0x28,0x28,0x73,0x75,0x62, - 0x3e,0x3e,0x31,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x49,0x44,0x58,0x5f,0x57,0x49, - 0x44,0x54,0x48,0x29,0x2a,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20, - 0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x63,0x3d,0x30,0x3b,0x20,0x69,0x63,0x3c,0x6e,0x75,0x6d,0x5f,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f, - 0x6e,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x63,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x72,0x3b, - 0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x2a,0x70,0x30,0x2c,0x2a,0x70,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28, - 0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3c,0x3d,0x38,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x38,0x29,0x29,0x0a,0x7b, - 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x73,0x70,0x4d,0x69,0x78,0x3d,0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x30,0x5e, - 0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x31,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x20,0x5e,0x3d,0x20,0x28,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x73,0x70,0x4d,0x69,0x78,0x29,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x20,0x5e,0x3d,0x20,0x28, - 0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x73,0x70,0x4d,0x69,0x78,0x29,0x5b,0x31,0x5d,0x3b,0x0a,0x73,0x70,0x41, - 0x64,0x64,0x72,0x30,0x20,0x26,0x3d,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x3b,0x0a,0x73,0x70,0x41,0x64, - 0x64,0x72,0x31,0x20,0x26,0x3d,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x36,0x34,0x3b,0x0a,0x70,0x30,0x3d,0x28,0x5f, - 0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x73,0x70, - 0x41,0x64,0x64,0x72,0x30,0x2b,0x73,0x75,0x62,0x2a,0x38,0x29,0x3b,0x0a,0x70,0x31,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36, - 0x34,0x5f,0x74,0x2a,0x29,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x2b,0x73,0x75,0x62,0x2a,0x38,0x29,0x3b, - 0x0a,0x72,0x3d,0x52,0x2b,0x73,0x75,0x62,0x3b,0x0a,0x2a,0x72,0x20,0x5e,0x3d,0x20,0x2a,0x70,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x5f,0x6d,0x65,0x6d,0x5f,0x64,0x61,0x74,0x61,0x3d,0x2a,0x70,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x71,0x3d,0x28,0x69, - 0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x26,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x6d,0x65,0x6d,0x5f,0x64,0x61,0x74,0x61,0x3b,0x0a,0x66,0x65,0x5b,0x30,0x5d,0x3d, - 0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f,0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x71,0x5b,0x30,0x5d,0x2c,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x2c,0x6f,0x72,0x4d, - 0x61,0x73,0x6b,0x31,0x29,0x3b,0x0a,0x66,0x65,0x5b,0x31,0x5d,0x3d,0x6c,0x6f,0x61,0x64,0x5f,0x46,0x5f,0x45,0x5f,0x67,0x72,0x6f,0x75,0x70,0x73,0x28,0x71,0x5b,0x31, - 0x5d,0x2c,0x61,0x6e,0x64,0x4d,0x61,0x73,0x6b,0x2c,0x6f,0x72,0x4d,0x61,0x73,0x6b,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52, - 0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3d,0x3d,0x49,0x44,0x58,0x5f,0x57,0x49,0x44,0x54,0x48,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x57,0x4f,0x52, - 0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x29,0x29,0x0a,0x66,0x70,0x72,0x63,0x3d,0x69,0x6e,0x6e,0x65,0x72,0x5f,0x6c,0x6f,0x6f,0x70,0x28, - 0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2c,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2c, - 0x73,0x75,0x62,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,0x66,0x70,0x5f,0x72,0x65,0x67,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x66,0x70,0x5f, - 0x72,0x65,0x67,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x41,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x52,0x2c,0x69,0x6d,0x6d,0x5f,0x62,0x75,0x66,0x2c,0x62,0x61,0x74, - 0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x66,0x70,0x72,0x63,0x2c,0x66,0x70,0x5f,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x2c,0x78,0x65,0x78, - 0x70,0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x2c,0x77,0x6f,0x72,0x6b,0x65,0x72,0x73,0x5f,0x6d,0x61,0x73,0x6b,0x29,0x3b,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f, - 0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f,0x48,0x41,0x53,0x48,0x3c,0x3d,0x38,0x29,0x7c,0x7c,0x28,0x73,0x75,0x62,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x6d, - 0x78,0x20,0x5e,0x3d,0x20,0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x32,0x5e,0x2a,0x72,0x65,0x61,0x64,0x52,0x65,0x67,0x33,0x3b,0x0a,0x6d,0x78,0x20,0x26,0x3d,0x20, - 0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34, - 0x5f,0x74,0x20,0x6e,0x65,0x78,0x74,0x5f,0x72,0x3d,0x2a,0x72,0x5e,0x2a,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, - 0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x64,0x61,0x74,0x61,0x73,0x65,0x74,0x2b,0x6d,0x61,0x2b,0x73,0x75,0x62,0x2a,0x38,0x29,0x3b,0x0a,0x2a,0x72,0x3d,0x6e, - 0x65,0x78,0x74,0x5f,0x72,0x3b,0x0a,0x2a,0x70,0x31,0x3d,0x6e,0x65,0x78,0x74,0x5f,0x72,0x3b,0x0a,0x2a,0x70,0x30,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28, - 0x66,0x5b,0x30,0x5d,0x29,0x5e,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x65,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74, - 0x6d,0x70,0x3d,0x6d,0x61,0x3b,0x0a,0x6d,0x61,0x3d,0x6d,0x78,0x3b,0x0a,0x6d,0x78,0x3d,0x74,0x6d,0x70,0x3b,0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x30,0x3d,0x30,0x3b, - 0x0a,0x73,0x70,0x41,0x64,0x64,0x72,0x31,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x57,0x4f,0x52,0x4b,0x45,0x52,0x53,0x5f,0x50,0x45,0x52,0x5f, - 0x48,0x41,0x53,0x48,0x3e,0x38,0x29,0x26,0x26,0x28,0x73,0x75,0x62,0x3e,0x3d,0x38,0x29,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36, - 0x34,0x5f,0x74,0x2a,0x29,0x76,0x6d,0x5f,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x2b,0x69,0x64,0x78,0x2a,0x28,0x56,0x4d,0x5f,0x53,0x54,0x41,0x54,0x45,0x5f,0x53,0x49, - 0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x5d,0x3d,0x52,0x5b,0x73, - 0x75,0x62,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x73,0x75,0x62,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x29,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x66,0x70,0x72,0x63,0x3b,0x0a,0x7d,0x0a,0x69,0x66, - 0x28,0x6c,0x61,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x2b,0x38,0x5d,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x46,0x5b,0x73,0x75,0x62, - 0x5d,0x29,0x5e,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x45,0x5b,0x73,0x75,0x62,0x5d,0x29,0x3b,0x0a,0x70,0x5b,0x73,0x75,0x62,0x2b,0x31,0x36,0x5d,0x3d,0x61, - 0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x45,0x5b,0x73,0x75,0x62,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x73,0x75,0x62,0x3d,0x3d, - 0x30,0x29,0x0a,0x7b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x70,0x2b,0x31,0x36,0x29, - 0x29,0x5b,0x30,0x5d,0x3d,0x6d,0x61,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x70, - 0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x6d,0x78,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28, - 0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f, - 0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6e,0x64,0x5f,0x73,0x68,0x61,0x72,0x65,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f, - 0x74,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f, - 0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x68,0x61,0x72,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a, - 0x34,0x2b,0x33,0x5d,0x3c,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64, - 0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x68,0x61,0x72,0x65,0x73,0x2b,0x30,0x78,0x46,0x46,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x64, - 0x78,0x3c,0x30,0x78,0x46,0x46,0x29,0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x73,0x74,0x61,0x72,0x74,0x5f,0x6e,0x6f,0x6e,0x63, - 0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e, - 0x49,0x54,0x49,0x41,0x4c,0x5f,0x48,0x41,0x53,0x48,0x5f,0x53,0x49,0x5a,0x45,0x20,0x36,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x4e,0x54,0x45,0x52, - 0x4d,0x45,0x44,0x49,0x41,0x54,0x45,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52, - 0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x2a,0x20,0x31,0x36,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x4d,0x50,0x49,0x4c,0x45, - 0x44,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x30,0x30,0x34,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x4e,0x55,0x4d, - 0x5f,0x56,0x47,0x50,0x52,0x5f,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x20,0x31,0x32,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74, - 0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x20,0x35,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65, - 0x20,0x31,0x31,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c, - 0x3c,0x20,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70, - 0x6f,0x6e,0x65,0x6e,0x74,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x53,0x69,0x7a,0x65,0x29, - 0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x65,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x61,0x73,0x20,0x31,0x30,0x32,0x33,0x0a, - 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x73,0x74,0x61,0x74,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x34,0x0a,0x23,0x64,0x65,0x66,0x69, - 0x6e,0x65,0x20,0x63,0x6f,0x6e,0x73,0x74,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42,0x69,0x74,0x73,0x20,0x30,0x78,0x33,0x30,0x30,0x0a,0x23,0x64,0x65,0x66,0x69, - 0x6e,0x65,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x4d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x4d,0x61,0x73,0x6b,0x20,0x28,0x28,0x31,0x55,0x4c,0x20,0x3c,0x3c,0x20, - 0x28,0x6d,0x61,0x6e,0x74,0x69,0x73,0x73,0x61,0x53,0x69,0x7a,0x65,0x20,0x2b,0x20,0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x45,0x78,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x42, - 0x69,0x74,0x73,0x29,0x29,0x20,0x2d,0x20,0x31,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d, - 0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x20,0x33,0x38,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d, - 0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x20,0x33,0x39,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d, - 0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x20,0x35,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d, - 0x61,0x73,0x6b,0x20,0x28,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x33,0x20,0x2d,0x20,0x38,0x29,0x0a, - 0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x42,0x49,0x54,0x53,0x20,0x38,0x0a,0x23,0x64,0x65,0x66, - 0x69,0x6e,0x65,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x20,0x38,0x0a,0x23,0x69,0x66,0x20,0x47,0x43, - 0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x53,0x45,0x54,0x50,0x43,0x5f, - 0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x20,0x30,0x78,0x62,0x65,0x38,0x30,0x32,0x30,0x30,0x63,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56, - 0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x20,0x30,0x78,0x33,0x36,0x33,0x38,0x30,0x30,0x30,0x65, - 0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x58,0x32,0x5f,0x53,0x43, - 0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x20,0x30,0x78,0x64,0x63,0x33,0x34,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, - 0x65,0x20,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x62, - 0x66,0x38,0x63,0x33,0x66,0x37,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f, - 0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x64,0x37,0x36,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65, - 0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x20,0x30,0x78,0x39,0x61,0x38,0x66,0x31, - 0x30,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x20,0x30,0x78,0x39,0x33, - 0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55, - 0x4c,0x5f,0x52,0x5f,0x32,0x20,0x30,0x78,0x39,0x61,0x38,0x66,0x66,0x66,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f, - 0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x20,0x30,0x78,0x39,0x61,0x61,0x31,0x30,0x65,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, - 0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x33,0x66,0x66,0x75, - 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30, - 0x78,0x39,0x61,0x38,0x66,0x32,0x30,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x20, - 0x30,0x78,0x38,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x58,0x4f, - 0x52,0x5f,0x52,0x20,0x30,0x78,0x62,0x65,0x62,0x65,0x30,0x33,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x52,0x20,0x30, - 0x78,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x20,0x30,0x78,0x38,0x66,0x30,0x30, - 0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4f,0x52,0x20,0x30,0x78,0x38,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x41,0x4e,0x44,0x20,0x30,0x78,0x38,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65, - 0x20,0x53,0x5f,0x42,0x46,0x45,0x20,0x30,0x78,0x39,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x53,0x5f,0x53,0x57, - 0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x20,0x30,0x78,0x64,0x38,0x64,0x34,0x38,0x30,0x30,0x31,0x75,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x35,0x36,0x34,0x30,0x30,0x33,0x63,0x75,0x0a,0x23,0x64,0x65,0x66, - 0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x33,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e, - 0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c, - 0x4f,0x41,0x44,0x5f,0x46,0x50,0x20,0x30,0x78,0x64,0x63,0x33,0x30,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x58,0x4f,0x52, - 0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x33,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x4d,0x55,0x4c,0x5f,0x46, - 0x36,0x34,0x20,0x30,0x78,0x64,0x35,0x36,0x35,0x30,0x30,0x34,0x34,0x75,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x53, - 0x45,0x54,0x50,0x43,0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x20,0x30,0x78,0x62,0x65,0x38,0x30,0x31,0x64,0x30,0x63,0x75,0x0a,0x23,0x64,0x65,0x66, - 0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x20,0x30,0x78,0x32,0x36,0x33, - 0x38,0x30,0x30,0x30,0x65,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44, - 0x58,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x20,0x30,0x78,0x64,0x63,0x35,0x34,0x38,0x30,0x30,0x30,0x75,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44, - 0x32,0x20,0x30,0x78,0x62,0x66,0x38,0x63,0x30,0x66,0x37,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45, - 0x5f,0x42,0x33,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x20,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x30, - 0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x20,0x30,0x78, - 0x39,0x36,0x30,0x66,0x31,0x30,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c, - 0x20,0x30,0x78,0x39,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33, - 0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x5f,0x32,0x20,0x30,0x78,0x39,0x36,0x30,0x66,0x66,0x66,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53, - 0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x20,0x30,0x78,0x39,0x36,0x32,0x31,0x30,0x65,0x31,0x30,0x75,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x20,0x30,0x78,0x62,0x65,0x61,0x30, - 0x30,0x30,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f, - 0x52,0x43,0x50,0x20,0x30,0x78,0x39,0x36,0x30,0x66,0x32,0x30,0x31,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33, - 0x32,0x5f,0x36,0x34,0x20,0x30,0x78,0x38,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42, - 0x33,0x32,0x5f,0x58,0x4f,0x52,0x5f,0x52,0x20,0x30,0x78,0x62,0x65,0x62,0x65,0x30,0x30,0x66,0x66,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c, - 0x53,0x48,0x52,0x20,0x30,0x78,0x38,0x66,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x20,0x30, - 0x78,0x38,0x65,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x4f,0x52,0x20,0x30,0x78,0x38,0x37,0x30,0x30,0x30,0x30, - 0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x41,0x4e,0x44,0x20,0x30,0x78,0x38,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64, - 0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x5f,0x42,0x46,0x45,0x20,0x30,0x78,0x39,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, - 0x44,0x53,0x5f,0x53,0x57,0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x20,0x30,0x78,0x64,0x38,0x37,0x61,0x38,0x30,0x30, - 0x31,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x32,0x38,0x30,0x30,0x30,0x33,0x63,0x75, - 0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x32,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23, - 0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48, - 0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x46,0x50,0x20,0x30,0x78,0x64,0x63,0x35,0x30,0x38,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20, - 0x56,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x20,0x30,0x78,0x32,0x61,0x30,0x30,0x30,0x30,0x30,0x30,0x75,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x56,0x5f, - 0x4d,0x55,0x4c,0x5f,0x46,0x36,0x34,0x20,0x30,0x78,0x64,0x32,0x38,0x31,0x30,0x30,0x34,0x34,0x75,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64, - 0x64,0x72,0x65,0x73,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c, - 0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x33,0x32,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61, - 0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x31,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28, - 0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f, - 0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x5f,0x43,0x41,0x4c,0x43,0x5f,0x41,0x44,0x44,0x52,0x45,0x53,0x53,0x7c,0x28,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3c,0x3c, - 0x39,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a, - 0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73, - 0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x33,0x32,0x2c,0x75,0x69,0x6e, - 0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x66, - 0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f, - 0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64, - 0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, - 0x78,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x58,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44, - 0x5f,0x4c,0x4f,0x41,0x44,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f, - 0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x35,0x34,0x33, - 0x39,0x30,0x32,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x31,0x31,0x63,0x36,0x61,0x32,0x62,0x75,0x3b,0x09, - 0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x31,0x61,0x39,0x30,0x31,0x30,0x33,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x64,0x63,0x35,0x34,0x30,0x30,0x30,0x30,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30, - 0x30,0x30,0x30,0x32,0x61,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a, - 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73, - 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70, - 0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x66, - 0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e,0x3d,0x30,0x29,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53,0x43,0x52,0x41, - 0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x28,0x76,0x6d,0x63,0x6e,0x74,0x26,0x31,0x35,0x29,0x7c,0x28,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e, - 0x3e,0x34,0x29,0x3c,0x3c,0x31,0x34,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x52,0x45,0x41,0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f, - 0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x31,0x34,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30, - 0x30,0x31,0x30,0x31,0x30,0x30,0x75,0x7c,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x52,0x45,0x41, - 0x44,0x4c,0x41,0x4e,0x45,0x5f,0x42,0x33,0x32,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x31,0x35,0x3b,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x30,0x30,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x29, - 0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74, - 0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x5f,0x5f,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x33,0x32, - 0x2c,0x75,0x69,0x6e,0x74,0x20,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a, - 0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x31,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x33,0x32,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x4e,0x44,0x5f,0x42,0x33,0x32,0x7c,0x30,0x78, - 0x33,0x38,0x30,0x30,0x30,0x65,0x75,0x7c,0x28,0x6d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56, - 0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x34,0x61,0x33,0x38,0x35,0x39,0x31,0x63,0x75,0x3b, - 0x0a,0x23,0x65,0x6c,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3d,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, - 0x30,0x78,0x36,0x38,0x33,0x38,0x35,0x39,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x33,0x38, - 0x35,0x39,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62, - 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4c,0x4f,0x41,0x44,0x5f,0x44,0x57,0x4f,0x52,0x44,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f, - 0x41,0x44,0x5f,0x46,0x50,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f, - 0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x35,0x34,0x33, - 0x39,0x30,0x32,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x31,0x31,0x63,0x36,0x61,0x32,0x62,0x75,0x3b,0x09, - 0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x31,0x61,0x39,0x30,0x31,0x30,0x33,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x64,0x63,0x35,0x30,0x30,0x30,0x30,0x30,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30, - 0x30,0x30,0x30,0x32,0x61,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a, - 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x73, - 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x5f,0x66,0x70,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, - 0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x29,0x0a,0x7b, - 0x0a,0x69,0x66,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3e,0x3d,0x30,0x29,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x57,0x41,0x49,0x54,0x43,0x4e,0x54,0x5f,0x53, - 0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x4f,0x41,0x44,0x32,0x7c,0x28,0x76,0x6d,0x63,0x6e,0x74,0x26,0x31,0x35,0x29,0x7c,0x28,0x28,0x76,0x6d,0x63, - 0x6e,0x74,0x3e,0x3e,0x34,0x29,0x3c,0x3c,0x31,0x34,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x39,0x30,0x30,0x75,0x7c, - 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c, - 0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x69,0x74,0x5f,0x65,0x6d,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x28,0x5f,0x5f,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6c,0x61,0x73,0x74, - 0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x2c, - 0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e, - 0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e, - 0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74, - 0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78, - 0x3e,0x3e,0x32,0x34,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44, - 0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x32, - 0x29,0x20,0x25,0x20,0x34,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x3e,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c, - 0x53,0x48,0x4c,0x7c,0x30,0x78,0x38,0x65,0x38,0x30,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x3c,0x3c,0x38, - 0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73, - 0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29, - 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x75,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28, - 0x64,0x73,0x74,0x3d,0x3d,0x35,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73, - 0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x3f,0x30,0x78,0x63,0x31, - 0x3a,0x30,0x78,0x38,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66, 0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73, 0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73, 0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68, @@ -3270,525 +3490,332 @@ static const char randomx_cl[130953] = { 0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72, 0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d, - 0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x66,0x31,0x31, - 0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a, - 0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x31, - 0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29, - 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x31,0x31,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b, - 0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37, - 0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x30, - 0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e, - 0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x3f,0x30,0x78,0x63,0x31,0x3a,0x30,0x78,0x38,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x72, - 0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x49,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e, - 0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28, + 0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28, + 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73, + 0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09, + 0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28, + 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a, + 0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79, + 0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x72,0x63,0x70,0x5f,0x76, + 0x61,0x6c,0x75,0x65,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x69,0x6d,0x75,0x6c,0x5f,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x28,0x69,0x6e,0x73, + 0x74,0x2e,0x79,0x29,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50, + 0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47, + 0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49, + 0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73, + 0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x32,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64, + 0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x32,0x31,0x31,0x63,0x75,0x2b,0x28,0x64,0x73, + 0x74,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f, + 0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b, + 0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x30,0x78,0x38,0x30,0x30,0x66,0x30,0x65,0x30,0x66,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c, + 0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x32,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09, + 0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09, + 0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30,0x32,0x30, + 0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e, + 0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f, + 0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47, + 0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x31,0x30,0x38,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x39, + 0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x31,0x31,0x38,0x30,0x75, + 0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x39,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a, + 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69, + 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a, + 0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32, + 0x5f,0x36,0x34,0x7c,0x30,0x78,0x39,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29, + 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69, + 0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x58,0x4f, + 0x52,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52, + 0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x7c,0x30,0x78,0x39,0x30,0x33,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f, + 0x36,0x34,0x7c,0x30,0x78,0x31,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b, + 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66, + 0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72, + 0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61, + 0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63, + 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d, + 0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74, + 0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70, + 0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73, + 0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72, + 0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f, + 0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32, + 0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34, + 0x7c,0x30,0x78,0x39,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d, + 0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69, + 0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78, + 0x61,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x38,0x30,0x38,0x66,0x31,0x30,0x63,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, + 0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x61,0x32,0x30,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65, + 0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x61,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, + 0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x38,0x66,0x31,0x30,0x63,0x30,0x75, + 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x61,0x32,0x30,0x66,0x31, + 0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, + 0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x3f,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3a,0x2d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x26,0x36,0x33,0x3b,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x61,0x30,0x38,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x68, + 0x69,0x66,0x74,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x61,0x32,0x38,0x30,0x31,0x30,0x75, + 0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4f,0x52,0x7c,0x30,0x78,0x39,0x30,0x32,0x32,0x32,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x72,0x65, + 0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, + 0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28, + 0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31, + 0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09, + 0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28, + 0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x32,0x30,0x75,0x7c,0x28,0x73,0x72, + 0x63,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x30,0x30, + 0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30, + 0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x32,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64, + 0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x44,0x53,0x5f,0x53,0x57,0x49,0x5a,0x5a, + 0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x63,0x30,0x30,0x30,0x30,0x33, + 0x63,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x32,0x35,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x44,0x53, + 0x5f,0x53,0x57,0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33, + 0x64,0x30,0x30,0x30,0x30,0x33,0x64,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x32,0x35,0x29,0x3b,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x66,0x38,0x63,0x63,0x30,0x37,0x66,0x75,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x32,0x36,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x28,0x73,0x72,0x63, + 0x26,0x33,0x29,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, + 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, + 0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28, 0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63, 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a, - 0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65, - 0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d, - 0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, - 0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65, - 0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65, - 0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74, - 0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, - 0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74, - 0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, - 0x78,0x38,0x30,0x39,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x39,0x31,0x30,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a, - 0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, - 0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63, - 0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x31,0x30,0x75,0x7c,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x32,0x31,0x31,0x63,0x75,0x2b,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63, - 0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c, - 0x30,0x78,0x30,0x65,0x31,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x30,0x66,0x30,0x65,0x30,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33, - 0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x31,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c, - 0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29, - 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30,0x31,0x30,0x31,0x30, - 0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d, - 0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x5f,0x32,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x66,0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x32, - 0x31,0x31,0x63,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30, - 0x66,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69, - 0x66,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, - 0x38,0x30,0x38,0x66,0x31,0x30,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d, - 0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x66,0x66,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66, - 0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d, - 0x55,0x4c,0x7c,0x30,0x78,0x31,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21, - 0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64, - 0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61, - 0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73, - 0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73, - 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69, - 0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, - 0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e, - 0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, - 0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70, - 0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x31,0x30,0x75,0x7c,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x31,0x64,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30, - 0x32,0x31,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x32,0x30,0x30,0x66,0x31,0x30,0x75,0x7c, - 0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x32,0x31,0x32,0x30,0x32,0x31,0x75,0x3b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x32,0x30,0x30,0x65,0x31,0x31,0x75,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x32,0x30,0x32,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x31,0x30, - 0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75, - 0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55, - 0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c, - 0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73, - 0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09, - 0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09, - 0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09, - 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70, - 0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73, - 0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31, - 0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61, - 0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, - 0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63, - 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69, - 0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70, - 0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b, - 0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a, - 0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63, - 0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, - 0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30, - 0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, - 0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65, - 0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x61,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, - 0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69, - 0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, - 0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e, - 0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c, - 0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c, - 0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09, - 0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29, - 0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x31,0x31,0x30,0x75,0x7c,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c, - 0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x38,0x75, - 0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a, - 0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28, - 0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63, - 0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f, - 0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c, - 0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x70,0x3d,0x6a, - 0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73, - 0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68, - 0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x28,0x70,0x2c, - 0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70, - 0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f, - 0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61, - 0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74, - 0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69, - 0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e, - 0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29, - 0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x38,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09, - 0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x36,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x38,0x75,0x3b,0x09,0x09,0x09, - 0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x30,0x65,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37, - 0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x69,0x66, - 0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, - 0x32,0x20,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x69,0x6d,0x75,0x6c,0x5f,0x72,0x63,0x70,0x5f,0x76,0x61, - 0x6c,0x75,0x65,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x4f,0x56,0x5f,0x42,0x33,0x32,0x5f,0x49, - 0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x78, - 0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, - 0x5f,0x4d,0x55,0x4c,0x5f,0x48,0x49,0x5f,0x55,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09, - 0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x33,0x38,0x30,0x32,0x32,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x36,0x30,0x30,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x32,0x31, - 0x31,0x63,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x32,0x38,0x39,0x30,0x30,0x30,0x66, - 0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x31,0x30,0x31,0x31,0x63,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x72,0x63,0x70,0x5f,0x76,0x61,0x6c,0x75,0x65,0x2e,0x79,0x3b,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x30,0x66,0x30,0x65,0x30,0x66,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c,0x7c,0x30,0x78,0x30,0x65,0x32,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x31,0x30,0x65,0x30,0x66,0x75,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x55,0x4c,0x5f,0x49,0x33,0x32,0x5f,0x49,0x4d,0x55,0x4c, - 0x7c,0x30,0x78,0x31,0x30,0x32,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d, - 0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, - 0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x39,0x30,0x31,0x30,0x38,0x30,0x75,0x7c, - 0x28,0x64,0x73,0x74,0x3c,0x3c,0x39,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32, - 0x39,0x31,0x31,0x31,0x38,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x39,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x72,0x65,0x74, - 0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e, - 0x45,0x47,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f, - 0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f, - 0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x7c,0x30,0x78,0x39,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64, - 0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x61, - 0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x3c,0x30,0x29,0x20,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4d,0x4f,0x56, - 0x5f,0x42,0x33,0x32,0x5f,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x7c,0x30,0x78,0x39,0x30,0x33,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31, - 0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58, - 0x4f,0x52,0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x7c,0x30,0x78,0x31,0x30,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73, - 0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72, - 0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52, - 0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f, - 0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a, - 0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64, - 0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20, - 0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x65,0x6c,0x73,0x65, - 0x20,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x66,0x69,0x78,0x65,0x64,0x5f,0x61,0x64, - 0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x2c, - 0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f, - 0x61,0x64,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63, - 0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, - 0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x58,0x4f,0x52, - 0x5f,0x42,0x33,0x32,0x5f,0x36,0x34,0x7c,0x30,0x78,0x39,0x30,0x30,0x65,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x37,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c, - 0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x20,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f, - 0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x61,0x30,0x31,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29, - 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x38,0x66,0x31,0x30,0x63,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x61,0x32,0x30,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b, - 0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x61,0x30,0x31,0x30,0x31,0x30, - 0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30, - 0x38,0x66,0x31,0x30,0x63,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x39,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c, - 0x30,0x78,0x61,0x32,0x30,0x66,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x0a,0x7b,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x29,0x3f,0x69,0x6e,0x73,0x74,0x2e,0x79,0x3a,0x2d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x29,0x26,0x36, - 0x33,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x61,0x30,0x38,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c, - 0x3c,0x31,0x29,0x7c,0x28,0x73,0x68,0x69,0x66,0x74,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78, - 0x61,0x32,0x38,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x28,0x36,0x34,0x2d,0x73,0x68,0x69,0x66,0x74,0x29,0x3c,0x3c,0x38,0x29, - 0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4f,0x52,0x7c,0x30,0x78,0x39,0x30,0x32,0x32,0x32,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c, - 0x31,0x37,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52, - 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52, - 0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49, - 0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74, - 0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34,0x31,0x30,0x75,0x7c,0x28,0x73,0x72, - 0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x34, - 0x32,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, - 0x30,0x78,0x62,0x65,0x61,0x30,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x39,0x30,0x30,0x31,0x32,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x09, - 0x09,0x09,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x44, - 0x53,0x5f,0x53,0x57,0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, - 0x33,0x63,0x30,0x30,0x30,0x30,0x33,0x63,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x32,0x35,0x29,0x3b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x44,0x53,0x5f,0x53,0x57,0x49,0x5a,0x5a,0x4c,0x45,0x5f,0x42,0x33,0x32,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x64,0x30,0x30,0x30,0x30,0x33,0x64,0x75,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x64,0x73,0x74,0x3c,0x3c,0x32, - 0x35,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x66,0x38,0x63,0x63,0x30,0x37,0x66,0x75,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52, - 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29, - 0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29, - 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x32,0x36,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31, - 0x29,0x2b,0x28,0x28,0x73,0x72,0x63,0x26,0x33,0x29,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72, - 0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63, - 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69, - 0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b, - 0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f, - 0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28, - 0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70, - 0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c, - 0x6f,0x61,0x64,0x32,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44, - 0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x32, - 0x33,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a, - 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69, - 0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x34,0x30,0x30,0x32,0x36,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28, - 0x28,0x73,0x72,0x63,0x26,0x33,0x29,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, - 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65, - 0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74, - 0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74, - 0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65, - 0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, - 0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, - 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69, - 0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64, - 0x32,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, - 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36, - 0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x34,0x30,0x30,0x32,0x33,0x39,0x33, - 0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x28,0x56,0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x7c,0x30,0x78,0x37,0x61,0x36,0x37,0x33,0x64,0x75,0x29,0x2b,0x28,0x28,0x64,0x73,0x74, - 0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x38,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b, - 0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a, - 0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x4d,0x55,0x4c,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x32,0x36,0x39,0x34,0x34,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29, - 0x2b,0x28,0x28,0x73,0x72,0x63,0x26,0x33,0x29,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65, - 0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72, - 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e, - 0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f, - 0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73, - 0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x70, - 0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, - 0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, - 0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f, - 0x61,0x64,0x32,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72, - 0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, - 0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49, - 0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x30,0x75,0x2b,0x28,0x28,0x64,0x73, - 0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33, - 0x30,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e, - 0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f, - 0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f, - 0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x32,0x38,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73, - 0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x32,0x38,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31, - 0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, - 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20, - 0x73,0x68,0x69,0x66,0x74,0x3d,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x4f,0x46,0x46,0x53, - 0x45,0x54,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x69,0x6d,0x6d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x7c,0x28,0x31,0x75,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29,0x3b, - 0x0a,0x69,0x6d,0x6d,0x20,0x26,0x3d,0x20,0x7e,0x28,0x31,0x75,0x3c,0x3c,0x28,0x73,0x68,0x69,0x66,0x74,0x2d,0x31,0x29,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, - 0x3d,0x30,0x78,0x38,0x30,0x31,0x30,0x66,0x66,0x31,0x30,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x69,0x6d,0x6d,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x30,0x31,0x31,0x75,0x7c,0x28, - 0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6d,0x6d,0x29, - 0x3c,0x30,0x29,0x3f,0x30,0x78,0x63,0x31,0x3a,0x30,0x78,0x38,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x63, - 0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61,0x73,0x6b,0x52,0x65,0x67,0x3d,0x37,0x30,0x2b,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3b,0x0a,0x2a,0x28,0x70, - 0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x41,0x4e,0x44,0x7c,0x30,0x78,0x30,0x65,0x30,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x63,0x6f, - 0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x4d,0x61,0x73,0x6b,0x52,0x65,0x67,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x65, - 0x6c,0x74,0x61,0x3d,0x28,0x28,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x70,0x29,0x2d,0x31,0x29,0x3b,0x0a, - 0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x66,0x38,0x34,0x30,0x30,0x30,0x30,0x75,0x7c,0x28,0x64,0x65,0x6c,0x74,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46, - 0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d, - 0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x36,0x33,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x3d,0x3d,0x36,0x33,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, - 0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x4c,0x7c,0x30,0x78,0x30,0x65,0x38,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x30,0x66,0x39,0x66,0x31,0x31,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b, - 0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4f,0x52,0x7c,0x30,0x78,0x30,0x65,0x30,0x66,0x30,0x65,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a, - 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x41,0x4e,0x44,0x7c,0x30,0x78,0x30,0x65,0x38,0x33,0x30,0x65,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x7d,0x0a,0x65,0x6c, - 0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x42,0x46,0x45,0x7c,0x30,0x78,0x38,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63, - 0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x73,0x68,0x69,0x66,0x74,0x7c,0x28,0x32,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x69, - 0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38, - 0x65,0x30,0x62,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x39,0x30,0x34,0x32,0x39,0x65,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b, - 0x2b,0x29,0x3d,0x30,0x78,0x62,0x39,0x63,0x32,0x30,0x38,0x38,0x31,0x75,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62, - 0x65,0x38,0x65,0x30,0x38,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x66,0x34,0x32,0x39,0x65,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x39,0x34,0x32,0x30,0x38,0x38,0x31,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, - 0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e, - 0x44,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45, - 0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3c,0x31,0x34, - 0x29,0x3f,0x28,0x28,0x6d,0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65, - 0x67,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x29,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70, - 0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63, - 0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x6d,0x61,0x73,0x6b,0x2c,0x62,0x61, - 0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x34,0x38, - 0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x30,0x30,0x30,0x32,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x76, - 0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x30,0x32,0x30,0x32,0x31,0x31,0x75, - 0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x23,0x69,0x66,0x20,0x47,0x43, - 0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20, - 0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x66,0x38,0x63,0x33,0x66,0x37,0x30,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66, - 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x63,0x37,0x34,0x38,0x30,0x30,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30, - 0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b, - 0x2b,0x29,0x3d,0x30,0x78,0x33,0x32,0x33,0x38,0x30,0x35,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x38,0x33,0x61,0x30,0x36,0x38, - 0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x63,0x37,0x34,0x30,0x30,0x30,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, - 0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a, - 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65, - 0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x2c,0x0a, - 0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x69,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x2c,0x0a,0x63, - 0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73, - 0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74, - 0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x0a,0x63,0x6f, - 0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x3b,0x0a,0x74, - 0x2e,0x78,0x3d,0x28,0x73,0x72,0x63,0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70, - 0x61,0x64,0x4c,0x33,0x4d,0x61,0x73,0x6b,0x29,0x3e,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x32, - 0x29,0x3f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3a,0x73,0x63,0x72,0x61, - 0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x3a,0x6d,0x61,0x78,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, - 0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x3b,0x0a,0x74,0x2e, - 0x79,0x3d,0x69,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x74,0x31,0x3d,0x74,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6c,0x61,0x73,0x74,0x42, - 0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3c,0x3d,0x74,0x31,0x29,0x26,0x26,0x28,0x74,0x31,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63, - 0x68,0x29,0x29,0x0a,0x7b,0x0a,0x74,0x2e,0x78,0x3d,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69, - 0x66,0x28,0x28,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3e,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x26, - 0x26,0x28,0x74,0x31,0x3c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x74,0x2e,0x78,0x3d,0x6c,0x61, - 0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3b,0x0a,0x7d,0x0a,0x70,0x30,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61, - 0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x5d,0x3d,0x74,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74, - 0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x67,0x65,0x6e,0x65, - 0x72,0x61,0x74,0x65,0x5f,0x6a,0x69,0x74,0x5f,0x63,0x6f,0x64,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x65,0x2c, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74, - 0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65, - 0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31, - 0x0a,0x66,0x6f,0x72,0x20,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x73,0x73,0x3d,0x30,0x3b,0x20,0x70,0x61,0x73,0x73,0x3c, - 0x32,0x3b,0x20,0x2b,0x2b,0x70,0x61,0x73,0x73,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d, - 0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x5b,0x38,0x5d,0x3d,0x7b,0x20,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31, - 0x20,0x7d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30, - 0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61, - 0x62,0x6c,0x65,0x41,0x74,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x2d,0x31, - 0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x3d,0x2d,0x31,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x38,0x5d,0x3d,0x7b,0x20,0x2d, - 0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a, - 0x75,0x6c,0x6f,0x6e,0x67,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63, - 0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x75,0x69,0x6e,0x74,0x20, - 0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65, - 0x74,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61, - 0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x30,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28, - 0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45, - 0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x30,0x29,0x0a,0x65,0x5b,0x69,0x5d,0x2e,0x78,0x20,0x26,0x3d,0x20,0x7e, - 0x28,0x30,0x78,0x66,0x38,0x75,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e, - 0x74,0x20,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, - 0x20,0x64,0x73,0x74,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73, - 0x72,0x63,0x3d,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x6f, - 0x64,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x32,0x34,0x3b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69, - 0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72, - 0x67,0x65,0x74,0x3d,0x69,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20, - 0x3e,0x20,0x32,0x35,0x36,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d, - 0x30,0x3b,0x20,0x6a,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, - 0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x6a,0x5d,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x5b,0x6a,0x5d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63, - 0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3b,0x0a,0x23,0x65,0x6e,0x64, - 0x69,0x66,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61, - 0x72,0x67,0x65,0x74,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x73,0x63,0x72,0x61, - 0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65, - 0x74,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x7d,0x0a,0x69, - 0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x3d,0x69, - 0x3b,0x0a,0x7d,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32, - 0x35,0x36,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67, - 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75, - 0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43, - 0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x2b,0x31,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20, - 0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x26,0x28,0x31,0x75,0x3c,0x3c,0x73,0x72,0x63,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x3e,0x3e,0x28,0x73,0x72,0x63,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61, - 0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x28,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, - 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3e,0x3e,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b, - 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x41,0x44,0x44,0x5f,0x52,0x53,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49, - 0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74, - 0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64, - 0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64, - 0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41, - 0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, - 0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c, - 0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29, - 0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a, - 0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61, - 0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73, - 0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61, - 0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74, + 0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65, + 0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78, + 0x3c,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x5f,0x66,0x70, + 0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64, + 0x65,0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28, + 0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x32,0x33,0x39,0x33,0x63,0x75,0x2b,0x28, + 0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30, + 0x78,0x34,0x30,0x30,0x32,0x36,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x28,0x73,0x72,0x63,0x26,0x33,0x29, + 0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f, + 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70, + 0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63, + 0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d,0x6f,0x64, + 0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70,0x3d,0x6a, + 0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a, + 0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c,0x3d,0x30, + 0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x5f,0x66,0x70,0x28,0x70,0x2c, + 0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, + 0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f, + 0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x56,0x5f,0x41,0x44,0x44,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74, + 0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x34,0x30,0x30,0x32,0x33,0x39,0x33,0x63,0x75,0x2b,0x28,0x28,0x64,0x73, + 0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x28,0x56, + 0x5f,0x58,0x4f,0x52,0x5f,0x42,0x33,0x32,0x7c,0x30,0x78,0x37,0x61,0x36,0x37,0x33,0x64,0x75,0x29,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29, + 0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x38,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x56,0x5f,0x4d,0x55,0x4c,0x5f,0x46,0x36,0x34,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x30,0x78,0x30,0x30,0x30,0x32,0x36,0x39,0x34,0x34,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x2b,0x28,0x28,0x73,0x72,0x63,0x26, + 0x33,0x29,0x3c,0x3c,0x31,0x30,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, + 0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3e,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64, + 0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x5f,0x66,0x70,0x28,0x70,0x2c,0x73,0x72,0x63,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x28,0x6d, + 0x6f,0x64,0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72, + 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x70, + 0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x5f,0x66,0x70,0x28,0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74, + 0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, + 0x78,0x3a,0x32,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3c, + 0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x6c,0x6f,0x61,0x64,0x32,0x5f,0x66,0x70,0x28, + 0x70,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3f,0x2d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, + 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3a,0x32,0x38,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65, + 0x78,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x30,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31, + 0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x32,0x31,0x33,0x30,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31, + 0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x33,0x30,0x75,0x2b,0x28,0x28,0x64,0x73, + 0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69, + 0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x62, + 0x63,0x32,0x31,0x32,0x38,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x62,0x65,0x62,0x63,0x31,0x65,0x32,0x38,0x75,0x2b,0x28,0x28,0x64,0x73,0x74,0x26,0x33,0x29,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64, + 0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, + 0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x28, + 0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x4a,0x55,0x4d,0x50,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x3b,0x0a,0x75,0x69,0x6e, + 0x74,0x20,0x69,0x6d,0x6d,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x7c,0x28,0x31,0x75,0x3c,0x3c,0x73,0x68,0x69,0x66,0x74,0x29,0x3b,0x0a,0x69,0x6d,0x6d,0x20,0x26,0x3d, + 0x20,0x7e,0x28,0x31,0x75,0x3c,0x3c,0x28,0x73,0x68,0x69,0x66,0x74,0x2d,0x31,0x29,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x30,0x31,0x30, + 0x66,0x66,0x31,0x30,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x69,0x6d,0x6d,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x32,0x31,0x31,0x30,0x30,0x31,0x31,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29, + 0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x37,0x29,0x7c,0x28,0x28,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x28,0x69,0x6d,0x6d,0x29,0x3c,0x30,0x29,0x3f,0x30,0x78,0x63, + 0x31,0x3a,0x30,0x78,0x38,0x30,0x29,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f, + 0x6e,0x4d,0x61,0x73,0x6b,0x52,0x65,0x67,0x3d,0x37,0x30,0x2b,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x41, + 0x4e,0x44,0x7c,0x30,0x78,0x30,0x65,0x30,0x30,0x31,0x30,0x75,0x7c,0x28,0x64,0x73,0x74,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x63,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e, + 0x4d,0x61,0x73,0x6b,0x52,0x65,0x67,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x65,0x6c,0x74,0x61,0x3d,0x28,0x28,0x6c, + 0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x70,0x29,0x2d,0x31,0x29,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, + 0x30,0x78,0x62,0x66,0x38,0x34,0x30,0x30,0x30,0x30,0x75,0x7c,0x28,0x64,0x65,0x6c,0x74,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52, + 0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52, + 0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x68,0x69,0x66,0x74,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26, + 0x36,0x33,0x3b,0x0a,0x69,0x66,0x28,0x73,0x68,0x69,0x66,0x74,0x3d,0x3d,0x36,0x33,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x4c,0x53,0x48, + 0x4c,0x7c,0x30,0x78,0x30,0x65,0x38,0x31,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, + 0x5f,0x4c,0x53,0x48,0x52,0x7c,0x30,0x78,0x30,0x66,0x39,0x66,0x31,0x31,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b, + 0x2b,0x29,0x3d,0x53,0x5f,0x4f,0x52,0x7c,0x30,0x78,0x30,0x65,0x30,0x66,0x30,0x65,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53, + 0x5f,0x41,0x4e,0x44,0x7c,0x30,0x78,0x30,0x65,0x38,0x33,0x30,0x65,0x75,0x3b,0x09,0x09,0x09,0x09,0x09,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x2a,0x28, + 0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x42,0x46,0x45,0x7c,0x30,0x78,0x38,0x65,0x66,0x66,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x3b,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x73,0x68,0x69,0x66,0x74,0x7c,0x28,0x32,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56, + 0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x62,0x30,0x65,0x75,0x3b, + 0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x39,0x30,0x34,0x32,0x39,0x65,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x39, + 0x63,0x32,0x30,0x38,0x38,0x31,0x75,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x65,0x38,0x65,0x30,0x38,0x30,0x65, + 0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x38,0x66,0x34,0x32,0x39,0x65,0x30,0x65,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78, + 0x62,0x39,0x34,0x32,0x30,0x38,0x38,0x31,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, + 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3c,0x31,0x34,0x29,0x3f,0x28,0x28,0x6d,0x6f,0x64, + 0x20,0x25,0x20,0x34,0x29,0x3f,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x31,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x3a,0x53,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x4c,0x32,0x4d,0x61,0x73,0x6b,0x5f,0x72,0x65,0x67,0x29,0x3a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73, + 0x6b,0x5f,0x72,0x65,0x67,0x3b,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x63,0x61,0x6c,0x63,0x5f,0x61,0x64,0x64, + 0x72,0x65,0x73,0x73,0x28,0x70,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2c,0x6d,0x61,0x73,0x6b,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, + 0x65,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x34,0x38,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b, + 0x29,0x3d,0x30,0x78,0x37,0x65,0x30,0x30,0x30,0x32,0x31,0x30,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c,0x31,0x29,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c, + 0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x37,0x65,0x30,0x32,0x30,0x32,0x31,0x31,0x75,0x7c,0x28,0x73,0x72,0x63,0x3c,0x3c, + 0x31,0x29,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x09,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49, + 0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x34,0x0a,0x23,0x69,0x66,0x20,0x47,0x43,0x4e,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x20,0x3e,0x3d,0x20,0x31,0x35,0x0a,0x2a, + 0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x62,0x66,0x38,0x63,0x33,0x66,0x37,0x30,0x75,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29, + 0x3d,0x30,0x78,0x64,0x63,0x37,0x34,0x38,0x30,0x30,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x63,0x75, + 0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x32, + 0x33,0x38,0x30,0x35,0x31,0x63,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x33,0x38,0x33,0x61,0x30,0x36,0x38,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70, + 0x2b,0x2b,0x29,0x3d,0x30,0x78,0x64,0x63,0x37,0x34,0x30,0x30,0x30,0x30,0x75,0x3b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30, + 0x31,0x63,0x75,0x7c,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x70,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45, + 0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72, + 0x65,0x61,0x64,0x28,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69, + 0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x20,0x69,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, + 0x20,0x64,0x73,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69, + 0x6e,0x74,0x20,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x63, + 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20, + 0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74, + 0x20,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74, + 0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x3b,0x0a,0x74,0x2e,0x78,0x3d,0x28,0x73,0x72,0x63, + 0x3d,0x3d,0x64,0x73,0x74,0x29,0x3f,0x28,0x28,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x4c,0x33,0x4d,0x61,0x73, + 0x6b,0x29,0x3e,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x53,0x43,0x52,0x41,0x54,0x43,0x48,0x50,0x41,0x44,0x5f,0x4c,0x32,0x29,0x3f,0x73,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41, + 0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x3a,0x6d,0x61,0x78,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61, + 0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x3b,0x0a,0x74,0x2e,0x79,0x3d,0x69,0x3b,0x0a,0x63,0x6f, + 0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x74,0x31,0x3d,0x74,0x2e,0x78,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61, + 0x72,0x67,0x65,0x74,0x3c,0x3d,0x74,0x31,0x29,0x26,0x26,0x28,0x74,0x31,0x3c,0x3d,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x29,0x0a,0x7b,0x0a,0x74, + 0x2e,0x78,0x3d,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x28,0x6c,0x61,0x73,0x74, + 0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3e,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x26,0x26,0x28,0x74,0x31,0x3c,0x6c,0x61, + 0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x29,0x0a,0x7b,0x0a,0x74,0x2e,0x78,0x3d,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63, + 0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3b,0x0a,0x7d,0x0a,0x70,0x30,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e, + 0x74,0x5d,0x3d,0x74,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74, + 0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x5f,0x6a,0x69, + 0x74,0x5f,0x63,0x6f,0x64,0x65,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x2c,0x75,0x69,0x6e, + 0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74, + 0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x76, + 0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x69,0x6e,0x74,0x20,0x70,0x61,0x73,0x73,0x3d,0x30,0x3b,0x20,0x70,0x61,0x73,0x73,0x3c,0x32,0x3b,0x20,0x2b,0x2b,0x70,0x61, + 0x73,0x73,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e, + 0x20,0x32,0x35,0x36,0x0a,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x38,0x5d,0x3d, + 0x7b,0x20,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x65,0x6c, + 0x73,0x65,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a, + 0x75,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69, + 0x66,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x30,0x3b,0x0a, + 0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x30, + 0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x2d,0x31,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6c, + 0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x3d,0x2d,0x31,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41, + 0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x38,0x5d,0x3d,0x7b,0x20,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31, + 0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x2c,0x2d,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x72, + 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74, + 0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61, + 0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68, + 0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x75,0x69, + 0x6e,0x74,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e, + 0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x30,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d, + 0x30,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d, + 0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a, + 0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x30,0x29,0x0a,0x65,0x5b,0x69,0x5d,0x2e,0x78,0x20,0x26,0x3d,0x20,0x7e,0x28,0x30,0x78,0x66,0x38,0x75,0x3c, + 0x3c,0x38,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x30,0x78,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x3d,0x28,0x69, + 0x6e,0x73,0x74,0x2e,0x78,0x3e,0x3e,0x38,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x3d,0x28,0x69,0x6e,0x73, + 0x74,0x2e,0x78,0x3e,0x3e,0x31,0x36,0x29,0x26,0x37,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6d,0x6f,0x64,0x3d,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x3e,0x3e,0x32,0x34,0x3b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28, + 0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x69,0x3b,0x0a, + 0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x23, + 0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x38,0x3b, + 0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63, + 0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x6a,0x5d,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x6a, + 0x5d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72, + 0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3b,0x0a, + 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74, + 0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x73,0x63,0x72,0x61, + 0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x73,0x63, + 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48, + 0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x73,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e, + 0x78,0x26,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x3d,0x69,0x3b,0x0a,0x7d,0x0a,0x23,0x69,0x66, + 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x63,0x6f,0x6e,0x73, + 0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, + 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74, + 0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b, + 0x64,0x73,0x74,0x5d,0x2b,0x31,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x72,0x63,0x41,0x76,0x61,0x69, + 0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x28,0x31,0x75,0x3c, + 0x3c,0x73,0x72,0x63,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3e,0x3e,0x28, + 0x73,0x72,0x63,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x64, + 0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65, + 0x64,0x26,0x28,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, + 0x67,0x65,0x64,0x3e,0x3e,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66, + 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x52,0x53,0x29, + 0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35, + 0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65, + 0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29, + 0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74, 0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44, - 0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42, - 0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e, - 0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b, - 0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38, - 0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63, - 0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x49,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49, - 0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a, - 0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d, - 0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73, - 0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69, - 0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e, - 0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73, - 0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61, - 0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b, - 0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b, - 0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73, - 0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, - 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28, - 0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61, - 0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e, - 0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f, - 0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d, - 0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32, - 0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23, - 0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74, - 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29, - 0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28, - 0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74, - 0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f, - 0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61, - 0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, - 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43, - 0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f, - 0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a, - 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a, - 0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a, + 0x44,0x5f,0x52,0x53,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44, + 0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20, + 0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69, + 0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67, + 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a, + 0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69, + 0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a, + 0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d, + 0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61, + 0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c, + 0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72, + 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63, + 0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d, + 0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23, + 0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a, + 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, + 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75, + 0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43, + 0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65, + 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x52,0x3b, + 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a, 0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36, 0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c, 0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, @@ -3801,301 +3828,345 @@ static const char randomx_cl[130953] = { 0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70, 0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67, 0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, - 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, + 0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73, + 0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, + 0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29, + 0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65, + 0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f, + 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69, 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65, 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43, 0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f, 0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a, - 0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d, - 0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32, - 0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23, - 0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74, - 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29, - 0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28, - 0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74, - 0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f, - 0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63, - 0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61, - 0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a, - 0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, - 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65, - 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65, - 0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69, - 0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c, - 0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66, - 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50, - 0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74, - 0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30, - 0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64, - 0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c, - 0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, - 0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, - 0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49, - 0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74, - 0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64, - 0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64, - 0x69,0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75, - 0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, - 0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76, - 0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c, - 0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72, - 0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65, - 0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b, - 0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52, - 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31, + 0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74, + 0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69, + 0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72, + 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67, + 0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61, + 0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41, + 0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d, 0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26, 0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c, 0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31, 0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, - 0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, - 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74, - 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28, - 0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65, - 0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c, - 0x3c,0x28,0x73,0x72,0x63,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x73,0x72,0x63,0x2a,0x38,0x29,0x29, - 0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x28,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x29,0x7c, - 0x28,0x31,0x75,0x3c,0x3c,0x73,0x72,0x63,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66, - 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a, - 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72, - 0x63,0x2c,0x30,0x78,0x46,0x46,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74, + 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, + 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74, + 0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69, + 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67, + 0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67, + 0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a, + 0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73, + 0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74, 0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41, 0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74, 0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e, - 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, - 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28, - 0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74, - 0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f, - 0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x30,0x78,0x46,0x46,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62, - 0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74, - 0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54, - 0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65, - 0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65, - 0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c, - 0x30,0x78,0x46,0x46,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68, - 0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72, - 0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f, - 0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d, - 0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70, - 0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f, - 0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x69,0x66, - 0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x41,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x32,0x3d,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x65,0x5b,0x64,0x73,0x74,0x41, - 0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x32,0x5d,0x2e,0x78,0x7c,0x3d,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x65,0x5b,0x69,0x5d,0x2e, - 0x78,0x7c,0x3d,0x28,0x30,0x78,0x34,0x30,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41, - 0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20, - 0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74, - 0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x6a,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x75,0x69,0x6e,0x74,0x20,0x74,0x3d,0x69,0x7c,0x28,0x69,0x3c, - 0x3c,0x38,0x29,0x3b,0x0a,0x74,0x3d,0x74,0x7c,0x28,0x74,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x3d,0x74,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65,0x67, - 0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, - 0x61,0x6e,0x67,0x65,0x64,0x3c,0x3c,0x33,0x32,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30, - 0x78,0x46,0x46,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, - 0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74, - 0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, - 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e, - 0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c, - 0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75, - 0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x3d,0x30,0x3b,0x20,0x72,0x65, - 0x67,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x72,0x65,0x67,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41, - 0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, - 0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x72,0x65,0x67,0x5d,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, - 0x6e,0x67,0x65,0x64,0x5b,0x72,0x65,0x67,0x5d,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x21,0x3d,0x61,0x76,0x61, - 0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x72,0x65,0x67,0x5d,0x3d,0x69,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e,0x73, - 0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x28, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74, - 0x26,0x28,0x31,0x75,0x3c,0x3c,0x72,0x65,0x67,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, - 0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3e,0x3e,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29, - 0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x28,0x31,0x75,0x3c,0x3c,0x72,0x65,0x67,0x29,0x29,0x3f,0x28,0x28,0x28, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3e,0x3e,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x26,0x30,0x78, - 0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x21,0x3d,0x61,0x76,0x61,0x69,0x6c,0x61, - 0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, - 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28, - 0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28, - 0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c, - 0x3c,0x72,0x65,0x67,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76, - 0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x21,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61, - 0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, - 0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61, - 0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x21,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67, - 0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x29,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69, - 0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, - 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f, - 0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69, - 0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f, - 0x55,0x4e,0x44,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f, - 0x52,0x45,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x65,0x5b,0x69,0x5d,0x2e,0x78,0x3d,0x69,0x6e,0x73,0x74,0x2e, - 0x78,0x7c,0x28,0x30,0x78,0x38,0x30,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64, - 0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3e,0x3d,0x31,0x34, - 0x29,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b, - 0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46, - 0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x76,0x3d,0x70,0x30,0x5b,0x30,0x5d,0x2e, - 0x78,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x31, - 0x3b,0x20,0x6a,0x3c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a, - 0x75,0x69,0x6e,0x74,0x32,0x20,0x63,0x75,0x72,0x3d,0x70,0x30,0x5b,0x6a,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x63,0x75,0x72,0x2e,0x78,0x3e,0x3d,0x70,0x72,0x65,0x76,0x29, - 0x0a,0x7b,0x0a,0x70,0x72,0x65,0x76,0x3d,0x63,0x75,0x72,0x2e,0x78,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x20,0x6a, - 0x31,0x3d,0x6a,0x2d,0x31,0x3b,0x0a,0x64,0x6f,0x20,0x7b,0x0a,0x70,0x30,0x5b,0x6a,0x31,0x2b,0x31,0x5d,0x3d,0x70,0x30,0x5b,0x6a,0x31,0x5d,0x3b,0x0a,0x2d,0x2d,0x6a, - 0x31,0x3b,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x6a,0x31,0x3e,0x3d,0x30,0x29,0x26,0x26,0x28,0x70,0x30,0x5b,0x6a,0x31,0x5d,0x2e,0x78,0x3e,0x3d, - 0x63,0x75,0x72,0x2e,0x78,0x29,0x29,0x3b,0x0a,0x70,0x30,0x5b,0x6a,0x31,0x2b,0x31,0x5d,0x3d,0x63,0x75,0x72,0x3b,0x0a,0x7d,0x0a,0x70,0x30,0x5b,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x5d,0x2e,0x78,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52, - 0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f, - 0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x30,0x2b,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2b,0x31,0x29,0x3b,0x0a,0x65,0x6e,0x75,0x6d,0x20,0x7b,0x20,0x6e,0x75, - 0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3d,0x32,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75, - 0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74, - 0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74, - 0x61,0x63,0x6b,0x5b,0x69,0x5d,0x3d,0x4e,0x55,0x4d,0x5f,0x56,0x47,0x50,0x52,0x5f,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x2d,0x32,0x2d,0x69,0x2a,0x32,0x3b, - 0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x3d, - 0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x2b,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63, - 0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69, - 0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20, - 0x2b,0x2b,0x69,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x20, - 0x6b,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x3d,0x70,0x30,0x5b,0x30,0x5d,0x3b,0x0a, - 0x69,0x6e,0x74,0x20,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74, - 0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x36,0x33,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, - 0x73,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x3d,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3b,0x0a, - 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65, - 0x74,0x3d,0x70,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x69,0x7a,0x65,0x5f,0x6c,0x69,0x6d,0x69,0x74,0x3d,0x28,0x43,0x4f,0x4d,0x50, - 0x49,0x4c,0x45,0x44,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x32,0x30,0x30,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69, - 0x6e,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x70,0x3d,0x70,0x3b,0x0a,0x23, - 0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c, - 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e, - 0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30, - 0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x70,0x3b,0x0a,0x62, - 0x6f,0x6f,0x6c,0x20,0x64,0x6f,0x6e,0x65,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x64,0x6f,0x20,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x6a,0x69,0x74,0x5f,0x69, - 0x6e,0x73,0x74,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78, - 0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3b,0x0a,0x69,0x66,0x28,0x21,0x64,0x6f,0x6e,0x65,0x26,0x26,0x28,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x2e,0x78,0x3d,0x3d,0x69,0x29,0x26,0x26,0x28,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x73,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x3e,0x30,0x29,0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74, - 0x65,0x72,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76, - 0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x5b,0x2d,0x2d,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f, - 0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x5d,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5b,0x70,0x72,0x65, - 0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x5d,0x3d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x7c,0x28,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74, - 0x65,0x72,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74, - 0x61,0x2e,0x79,0x5d,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x76,0x67, - 0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3d,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x73,0x5f, - 0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x36,0x33,0x3b,0x0a,0x2b,0x2b,0x6b,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x64,0x61,0x74,0x61,0x3d,0x70,0x30,0x5b,0x6b,0x5d,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70, - 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x64,0x61,0x74,0x61,0x3d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f, - 0x76,0x67,0x70,0x72,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x70,0x72,0x65,0x66, - 0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x64,0x61,0x74,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20, - 0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x76,0x5f,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f, - 0x76,0x67,0x70,0x72,0x73,0x5f,0x64,0x61,0x74,0x61,0x3e,0x3e,0x31,0x36,0x3b,0x0a,0x69,0x66,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x29,0x0a,0x70,0x72,0x65,0x66, - 0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x5b,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67, - 0x70,0x72,0x73,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x2b,0x2b,0x5d,0x3d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73, - 0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x38,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a, - 0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x36,0x33,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20, - 0x76,0x6d,0x63,0x6e,0x74,0x3d,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x2d,0x70,0x72,0x65,0x76,0x5f,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74, - 0x65,0x72,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x3d,0x69,0x6e,0x73,0x74,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f, - 0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x2d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3d,0x28, - 0x76,0x6d,0x63,0x6e,0x74,0x3c,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x2d,0x31,0x3b, - 0x0a,0x69,0x66,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3c,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x0a,0x73,0x5f,0x77,0x61,0x69, - 0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x76,0x6d,0x63,0x6e,0x74,0x3b,0x0a,0x64,0x6f,0x6e,0x65,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x70, - 0x3d,0x6a,0x69,0x74,0x5f,0x65,0x6d,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x28,0x70,0x2c,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61, - 0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x2c,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, - 0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2c,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65, - 0x29,0x3b,0x0a,0x69,0x66,0x28,0x70,0x2d,0x73,0x74,0x61,0x72,0x74,0x5f,0x70,0x3e,0x73,0x69,0x7a,0x65,0x5f,0x6c,0x69,0x6d,0x69,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x28, - 0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x53,0x45,0x54,0x50,0x43,0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x3b,0x20,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e, - 0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x21,0x64,0x6f,0x6e,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d, - 0x53,0x5f,0x53,0x45,0x54,0x50,0x43,0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x3b,0x20,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d, - 0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f, - 0x73,0x69,0x7a,0x65,0x28,0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x61,0x6e, - 0x64,0x6f,0x6d,0x78,0x5f,0x6a,0x69,0x74,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79, - 0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x69,0x6e,0x74,0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x74,0x65,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73, - 0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61, - 0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x6f,0x75,0x6e, - 0x64,0x69,0x6e,0x67,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74, - 0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64, - 0x28,0x30,0x29,0x2f,0x33,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x75,0x62,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x33,0x32,0x3b,0x0a,0x69,0x66,0x28,0x73,0x75,0x62,0x21,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b, - 0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x65,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, - 0x74,0x32,0x2a,0x29,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x45,0x4e,0x54,0x52,0x4f, - 0x50,0x59,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2b,0x28,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65, - 0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x3d, - 0x69,0x6e,0x74,0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x74,0x65,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64, - 0x65,0x78,0x2a,0x28,0x49,0x4e,0x54,0x45,0x52,0x4d,0x45,0x44,0x49,0x41,0x54,0x45,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69, - 0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x32,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x3d,0x70, - 0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x43,0x4f,0x4d,0x50,0x49,0x4c,0x45,0x44,0x5f,0x50, - 0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x29,0x3b,0x0a,0x67,0x65,0x6e,0x65,0x72, - 0x61,0x74,0x65,0x5f,0x6a,0x69,0x74,0x5f,0x63,0x6f,0x64,0x65,0x28,0x65,0x2c,0x70,0x30,0x2c,0x70,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b, - 0x0a,0x69,0x66,0x28,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5b,0x67,0x6c,0x6f,0x62,0x61, - 0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x52,0x3d,0x72,0x65, - 0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x33,0x32,0x3b,0x0a,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79, - 0x2b,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x45,0x4e,0x54,0x52,0x4f,0x50,0x59,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a, - 0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x3b,0x0a,0x52,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x32, - 0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x33,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x34,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x35,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x36, - 0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x37,0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x41,0x3d, - 0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x32,0x34,0x29,0x3b,0x0a,0x41,0x5b,0x30,0x5d,0x3d,0x67, - 0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79, - 0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74, - 0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x32,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50, - 0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x32,0x5d,0x29,0x3b,0x0a,0x41,0x5b, - 0x33,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74, - 0x72,0x6f,0x70,0x79,0x5b,0x33,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x34,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46, - 0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x34,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x35,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d, - 0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x35,0x5d,0x29, - 0x3b,0x0a,0x41,0x5b,0x36,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73, - 0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x36,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x37,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74, - 0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x37,0x5d,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c, - 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x38,0x5d, - 0x26,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20, - 0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x75,0x69, - 0x6e,0x74,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x32,0x5d,0x3b, - 0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x30,0x2b,0x28, - 0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69, - 0x73,0x74,0x65,0x72,0x73,0x20,0x3e,0x3e,0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52, - 0x2b,0x31,0x37,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x32,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b, - 0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x3e,0x3e,0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x32,0x5d,0x3d,0x34,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52, - 0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x3e,0x3e, - 0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x33,0x5d, - 0x3d,0x36,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f, - 0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x39,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x33, - 0x5d,0x26,0x44,0x61,0x74,0x61,0x73,0x65,0x74,0x45,0x78,0x74,0x72,0x61,0x49,0x74,0x65,0x6d,0x73,0x29,0x2a,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69, - 0x7a,0x65,0x3b,0x0a,0x52,0x5b,0x32,0x30,0x5d,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31, - 0x34,0x5d,0x29,0x3b,0x0a,0x52,0x5b,0x32,0x31,0x5d,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b, - 0x31,0x35,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x00 + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e, + 0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, + 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c, + 0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26, + 0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c, + 0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31, + 0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64, + 0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66, + 0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69, + 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65, + 0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43, + 0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f, + 0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31, + 0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74, + 0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69, + 0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72, + 0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67, + 0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61, + 0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x4d,0x55,0x4c,0x48,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74, + 0x2e,0x79,0x26,0x28,0x69,0x6e,0x73,0x74,0x2e,0x79,0x2d,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f, + 0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, + 0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68, + 0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46, + 0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74, + 0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73, + 0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4d,0x55,0x4c,0x5f,0x52,0x43,0x50,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, + 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f, + 0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64, + 0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, + 0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c, + 0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b, + 0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65, + 0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x4e,0x45,0x47,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x52, + 0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x29, + 0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35, + 0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65, + 0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29, + 0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x69,0x66,0x28,0x70, + 0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f, + 0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63, + 0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x64,0x73,0x74,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65, + 0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68, + 0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72, + 0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x58,0x4f,0x52,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63, + 0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f, + 0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52, + 0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65, + 0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e, + 0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75, + 0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38, + 0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b, + 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f,0x52,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x52,0x4f, + 0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41, + 0x50,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x73,0x72,0x63,0x21,0x3d,0x64,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d, + 0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73, + 0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x5b,0x73,0x72,0x63,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43, + 0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78, + 0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73, + 0x74,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69, + 0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c,0x3c,0x28,0x73,0x72,0x63,0x2a,0x38, + 0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x73,0x72,0x63,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73, + 0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x28,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x29,0x7c,0x28,0x31,0x75,0x3c,0x3c,0x73,0x72, + 0x63,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, + 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x57,0x41,0x50,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65, + 0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d, + 0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x57,0x41,0x50,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30, + 0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x30,0x78,0x46,0x46,0x2c, + 0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76, + 0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, + 0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29, + 0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52, + 0x45,0x51,0x5f,0x46,0x41,0x44,0x44,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45, + 0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31, + 0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74, + 0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69, + 0x2c,0x73,0x72,0x63,0x2c,0x30,0x78,0x46,0x46,0x2c,0x69,0x6e,0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63, + 0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69, + 0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c, + 0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d, + 0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x55,0x42,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x43,0x41,0x4c,0x5f,0x52,0x2b,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x4d,0x55,0x4c,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x46,0x44,0x49,0x56,0x5f,0x4d,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x31,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64, + 0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3d,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x72,0x65,0x61,0x64,0x28,0x70,0x30,0x2c,0x70, + 0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2c,0x69,0x2c,0x73,0x72,0x63,0x2c,0x30,0x78,0x46,0x46,0x2c,0x69,0x6e, + 0x73,0x74,0x2c,0x73,0x72,0x63,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69, + 0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x2c,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41, + 0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x6c,0x61,0x73,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x29,0x3b,0x0a, + 0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51, + 0x5f,0x46,0x44,0x49,0x56,0x5f,0x4d,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f, + 0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x46,0x53,0x51,0x52,0x54,0x5f,0x52,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52, + 0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d, + 0x30,0x29,0x0a,0x7b,0x0a,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x75,0x69,0x6e,0x74,0x20,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41, + 0x74,0x32,0x3d,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3b,0x0a,0x65,0x5b,0x64,0x73,0x74,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c, + 0x65,0x41,0x74,0x32,0x5d,0x2e,0x78,0x7c,0x3d,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x65,0x5b,0x69,0x5d,0x2e,0x78,0x7c,0x3d,0x28,0x30,0x78,0x34, + 0x30,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20, + 0x3e,0x20,0x32,0x35,0x36,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d, + 0x30,0x3b,0x20,0x6a,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, + 0x5b,0x6a,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x75,0x69,0x6e,0x74,0x20,0x74,0x3d,0x69,0x7c,0x28,0x69,0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x74,0x3d, + 0x74,0x7c,0x28,0x74,0x3c,0x3c,0x31,0x36,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x74, + 0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61, + 0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3c,0x3c, + 0x33,0x32,0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3d,0x30,0x78,0x46,0x46,0x3b,0x0a,0x23,0x65, + 0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41, + 0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20,0x3e,0x20,0x32,0x35,0x36,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64, + 0x5b,0x64,0x73,0x74,0x5d,0x3d,0x69,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67, + 0x65,0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c, + 0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x64,0x73,0x74,0x2a,0x38,0x29, + 0x29,0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x64,0x73,0x74,0x3b,0x0a, + 0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x65,0x67,0x3d,0x30,0x3b,0x20,0x72,0x65,0x67,0x3c,0x38,0x3b,0x20,0x2b,0x2b, + 0x72,0x65,0x67,0x29,0x0a,0x7b,0x0a,0x23,0x69,0x66,0x20,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x20, + 0x3e,0x20,0x32,0x35,0x36,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e, + 0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72, + 0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x5b,0x72,0x65,0x67,0x5d,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76, + 0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x5b,0x72,0x65, + 0x67,0x5d,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x21,0x3d,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41, + 0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61, + 0x6e,0x67,0x65,0x64,0x5b,0x72,0x65,0x67,0x5d,0x3d,0x69,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20, + 0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x26,0x28,0x31,0x75,0x3c,0x3c,0x72, + 0x65,0x67,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x41,0x74,0x42,0x72,0x61, + 0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x3e,0x3e,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a,0x30,0x3b,0x0a, + 0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x28,0x31,0x75,0x3c,0x3c,0x72,0x65,0x67,0x29,0x29,0x3f,0x28,0x28,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65, + 0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x3e,0x3e,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x26,0x30,0x78,0x46,0x46,0x29,0x2b,0x31,0x29,0x3a, + 0x30,0x3b,0x0a,0x69,0x66,0x28,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x21,0x3d,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72, + 0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65, + 0x64,0x3d,0x28,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x4c,0x61,0x73,0x74,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x26,0x7e,0x28,0x30,0x78,0x46,0x46,0x75,0x6c,0x3c, + 0x3c,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29,0x29,0x7c,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x28,0x69,0x29,0x3c,0x3c,0x28,0x72,0x65,0x67,0x2a,0x38,0x29,0x29, + 0x3b,0x0a,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x57,0x61,0x73,0x43,0x68,0x61,0x6e,0x67,0x65,0x64,0x7c,0x3d,0x31,0x75,0x3c,0x3c,0x72,0x65,0x67,0x3b,0x0a,0x7d, + 0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65, + 0x41,0x74,0x42,0x72,0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x21,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61, + 0x62,0x6c,0x65,0x41,0x74,0x29,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31, + 0x3b,0x0a,0x69,0x66,0x28,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x42,0x72, + 0x61,0x6e,0x63,0x68,0x54,0x61,0x72,0x67,0x65,0x74,0x21,0x3d,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61, + 0x62,0x6c,0x65,0x41,0x74,0x29,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74, + 0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x42,0x52,0x41,0x4e,0x43,0x48,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44, + 0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a, + 0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x43,0x46,0x52,0x4f,0x55,0x4e,0x44,0x3b,0x0a,0x69,0x66, + 0x28,0x6f,0x70,0x63,0x6f,0x64,0x65,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54,0x4f,0x52,0x45,0x29,0x0a,0x7b,0x0a,0x69, + 0x66,0x28,0x70,0x61,0x73,0x73,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x65,0x5b,0x69,0x5d,0x2e,0x78,0x3d,0x69,0x6e,0x73,0x74,0x2e,0x78,0x7c,0x28,0x30,0x78,0x38,0x30, + 0x3c,0x3c,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x41,0x76,0x61,0x69,0x6c,0x61,0x62, + 0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x28,0x6d,0x6f,0x64,0x3e,0x3e,0x34,0x29,0x3e,0x3d,0x31,0x34,0x29,0x0a,0x73,0x63,0x72,0x61,0x74, + 0x63,0x68,0x70,0x61,0x64,0x48,0x69,0x67,0x68,0x41,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x41,0x74,0x3d,0x69,0x2b,0x31,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x74, + 0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x6f,0x70,0x63,0x6f,0x64,0x65,0x2d,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x46,0x52,0x45,0x51,0x5f,0x49,0x53,0x54, + 0x4f,0x52,0x45,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x76,0x3d,0x70,0x30,0x5b,0x30,0x5d,0x2e,0x78,0x3b,0x0a,0x23,0x70,0x72,0x61, + 0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x31,0x3b,0x20,0x6a,0x3c,0x70,0x72,0x65, + 0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x63, + 0x75,0x72,0x3d,0x70,0x30,0x5b,0x6a,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x63,0x75,0x72,0x2e,0x78,0x3e,0x3d,0x70,0x72,0x65,0x76,0x29,0x0a,0x7b,0x0a,0x70,0x72,0x65,0x76, + 0x3d,0x63,0x75,0x72,0x2e,0x78,0x3b,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x31,0x3d,0x6a,0x2d,0x31,0x3b,0x0a, + 0x64,0x6f,0x20,0x7b,0x0a,0x70,0x30,0x5b,0x6a,0x31,0x2b,0x31,0x5d,0x3d,0x70,0x30,0x5b,0x6a,0x31,0x5d,0x3b,0x0a,0x2d,0x2d,0x6a,0x31,0x3b,0x0a,0x7d,0x20,0x77,0x68, + 0x69,0x6c,0x65,0x20,0x28,0x28,0x6a,0x31,0x3e,0x3d,0x30,0x29,0x26,0x26,0x28,0x70,0x30,0x5b,0x6a,0x31,0x5d,0x2e,0x78,0x3e,0x3d,0x63,0x75,0x72,0x2e,0x78,0x29,0x29, + 0x3b,0x0a,0x70,0x30,0x5b,0x6a,0x31,0x2b,0x31,0x5d,0x3d,0x63,0x75,0x72,0x3b,0x0a,0x7d,0x0a,0x70,0x30,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61, + 0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x5d,0x2e,0x78,0x3d,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45, + 0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73, + 0x74,0x61,0x63,0x6b,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x70,0x30,0x2b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x5f,0x64,0x61,0x74,0x61,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x2b,0x31,0x29,0x3b,0x0a,0x65,0x6e,0x75,0x6d,0x20,0x7b,0x20,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65, + 0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3d,0x32,0x31,0x20,0x7d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66, + 0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72, + 0x73,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x5b,0x69,0x5d,0x3d, + 0x4e,0x55,0x4d,0x5f,0x56,0x47,0x50,0x52,0x5f,0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x53,0x2d,0x32,0x2d,0x69,0x2a,0x32,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x3d,0x70,0x72,0x65,0x66,0x65,0x63,0x74, + 0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x2b,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73, + 0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b, + 0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x70,0x72, + 0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x30,0x3b,0x0a,0x75,0x69, + 0x6e,0x74,0x32,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x3d,0x70,0x30,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6d,0x65,0x6d, + 0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3d,0x30,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d, + 0x36,0x33,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x61,0x76,0x61,0x69,0x6c, + 0x61,0x62,0x6c,0x65,0x3d,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x70,0x3b,0x0a,0x63,0x6f, + 0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x69,0x7a,0x65,0x5f,0x6c,0x69,0x6d,0x69,0x74,0x3d,0x28,0x43,0x4f,0x4d,0x50,0x49,0x4c,0x45,0x44,0x5f,0x50,0x52, + 0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x32,0x30,0x30,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x3b,0x0a,0x5f,0x5f, + 0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x70,0x3d,0x70,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20, + 0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x58, + 0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74, + 0x32,0x20,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78,0x32,0x30,0x3c,0x3c,0x38,0x29, + 0x29,0x0a,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72,0x67,0x65,0x74,0x3d,0x70,0x3b,0x0a,0x62,0x6f,0x6f,0x6c,0x20,0x64,0x6f,0x6e, + 0x65,0x3d,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0a,0x64,0x6f,0x20,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x3b,0x0a,0x69,0x6e, + 0x74,0x20,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6a, + 0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3b,0x0a,0x69,0x66,0x28,0x21,0x64,0x6f,0x6e,0x65,0x26,0x26,0x28,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61, + 0x74,0x61,0x2e,0x78,0x3d,0x3d,0x69,0x29,0x26,0x26,0x28,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x61,0x76, + 0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x3e,0x30,0x29,0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x63,0x6f,0x6e, + 0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x73,0x74, + 0x61,0x63,0x6b,0x5b,0x2d,0x2d,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x61,0x76,0x61,0x69,0x6c,0x61,0x62, + 0x6c,0x65,0x5d,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64, + 0x61,0x74,0x61,0x2e,0x79,0x5d,0x3d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x7c,0x28,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3c,0x3c,0x31,0x36,0x29, + 0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x3d,0x65,0x5b,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x2e,0x79,0x5d,0x3b,0x0a,0x6a, + 0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a, + 0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3d,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74, + 0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x36,0x33,0x3b,0x0a,0x2b,0x2b,0x6b,0x3b,0x0a,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x64,0x61,0x74,0x61,0x3d,0x70,0x30, + 0x5b,0x6b,0x5d,0x3b,0x0a,0x7d,0x0a,0x65,0x6c,0x73,0x65,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68, + 0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x64,0x61,0x74,0x61,0x3d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5b,0x69, + 0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f, + 0x76,0x67,0x70,0x72,0x73,0x5f,0x64,0x61,0x74,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x72,0x65, + 0x76,0x5f,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3d,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x65,0x64,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x64, + 0x61,0x74,0x61,0x3e,0x3e,0x31,0x36,0x3b,0x0a,0x69,0x66,0x28,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x29,0x0a,0x70,0x72,0x65,0x66,0x65,0x63,0x74,0x68,0x5f,0x76,0x67, + 0x70,0x72,0x73,0x5f,0x73,0x74,0x61,0x63,0x6b,0x5b,0x6e,0x75,0x6d,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x73,0x5f,0x61,0x76,0x61, + 0x69,0x6c,0x61,0x62,0x6c,0x65,0x2b,0x2b,0x5d,0x3d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a,0x69,0x66,0x28,0x69,0x6e,0x73,0x74,0x2e,0x78,0x26,0x28,0x30,0x78, + 0x38,0x30,0x3c,0x3c,0x38,0x29,0x29,0x0a,0x7b,0x0a,0x2b,0x2b,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x73,0x5f,0x77,0x61,0x69,0x74,0x63, + 0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x3d,0x36,0x33,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x76,0x6d,0x63,0x6e,0x74,0x3d,0x6d, + 0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x2d,0x70,0x72,0x65,0x76,0x5f,0x6d,0x65,0x6d,0x5f,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x6a,0x69,0x74, + 0x5f,0x69,0x6e,0x73,0x74,0x3d,0x69,0x6e,0x73,0x74,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69,0x6e, + 0x64,0x65,0x78,0x3d,0x2d,0x76,0x67,0x70,0x72,0x5f,0x69,0x64,0x3b,0x0a,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x3d,0x28,0x76,0x6d,0x63,0x6e,0x74,0x3c,0x73, + 0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x3f,0x76,0x6d,0x63,0x6e,0x74,0x3a,0x2d,0x31,0x3b,0x0a,0x69,0x66,0x28,0x76,0x6d,0x63, + 0x6e,0x74,0x3c,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61,0x6c,0x75,0x65,0x29,0x0a,0x73,0x5f,0x77,0x61,0x69,0x74,0x63,0x6e,0x74,0x5f,0x76,0x61, + 0x6c,0x75,0x65,0x3d,0x76,0x6d,0x63,0x6e,0x74,0x3b,0x0a,0x64,0x6f,0x6e,0x65,0x3d,0x74,0x72,0x75,0x65,0x3b,0x0a,0x7d,0x0a,0x70,0x3d,0x6a,0x69,0x74,0x5f,0x65,0x6d, + 0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6f,0x6e,0x28,0x70,0x2c,0x6c,0x61,0x73,0x74,0x5f,0x62,0x72,0x61,0x6e,0x63,0x68,0x5f,0x74,0x61,0x72, + 0x67,0x65,0x74,0x2c,0x6a,0x69,0x74,0x5f,0x69,0x6e,0x73,0x74,0x2c,0x6a,0x69,0x74,0x5f,0x70,0x72,0x65,0x66,0x65,0x74,0x63,0x68,0x5f,0x76,0x67,0x70,0x72,0x5f,0x69, + 0x6e,0x64,0x65,0x78,0x2c,0x6a,0x69,0x74,0x5f,0x76,0x6d,0x63,0x6e,0x74,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x69,0x66,0x28,0x70, + 0x2d,0x73,0x74,0x61,0x72,0x74,0x5f,0x70,0x3e,0x73,0x69,0x7a,0x65,0x5f,0x6c,0x69,0x6d,0x69,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f, + 0x53,0x45,0x54,0x50,0x43,0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x3b,0x20,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x7d, + 0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x21,0x64,0x6f,0x6e,0x65,0x29,0x3b,0x0a,0x7d,0x0a,0x2a,0x28,0x70,0x2b,0x2b,0x29,0x3d,0x53,0x5f,0x53,0x45,0x54,0x50,0x43, + 0x5f,0x42,0x36,0x34,0x5f,0x53,0x31,0x32,0x5f,0x31,0x33,0x3b,0x20,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x70,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72, + 0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x36,0x34, + 0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x61,0x6e,0x64,0x6f,0x6d,0x78,0x5f,0x6a,0x69, + 0x74,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x32,0x2a,0x20,0x69,0x6e,0x74,0x65,0x72,0x6d,0x65,0x64,0x69,0x61,0x74,0x65,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2c,0x75,0x69,0x6e,0x74,0x20,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a, + 0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x2c,0x75,0x69, + 0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x74,0x65,0x72,0x61,0x74,0x69,0x6f,0x6e,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67, + 0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x33,0x32,0x3b, + 0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x73,0x75,0x62,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29, + 0x20,0x25,0x20,0x33,0x32,0x3b,0x0a,0x69,0x66,0x28,0x73,0x75,0x62,0x21,0x3d,0x30,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x65,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x29,0x28,0x65,0x6e, + 0x74,0x72,0x6f,0x70,0x79,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x45,0x4e,0x54,0x52,0x4f,0x50,0x59,0x5f,0x53,0x49,0x5a,0x45, + 0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x29,0x2b,0x28,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f,0x6e, + 0x67,0x29,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x32,0x2a,0x20,0x70,0x30,0x3d,0x69,0x6e,0x74,0x65,0x72,0x6d,0x65, + 0x64,0x69,0x61,0x74,0x65,0x5f,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x49,0x4e,0x54, + 0x45,0x52,0x4d,0x45,0x44,0x49,0x41,0x54,0x45,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69, + 0x6e,0x74,0x32,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x70,0x3d,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x73, + 0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x43,0x4f,0x4d,0x50,0x49,0x4c,0x45,0x44,0x5f,0x50,0x52,0x4f,0x47,0x52,0x41,0x4d,0x5f, + 0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x29,0x29,0x3b,0x0a,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x5f,0x6a,0x69,0x74, + 0x5f,0x63,0x6f,0x64,0x65,0x28,0x65,0x2c,0x70,0x30,0x2c,0x70,0x2c,0x62,0x61,0x74,0x63,0x68,0x5f,0x73,0x69,0x7a,0x65,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x74,0x65, + 0x72,0x61,0x74,0x69,0x6f,0x6e,0x3d,0x3d,0x30,0x29,0x0a,0x72,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78, + 0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x52,0x3d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73, + 0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x33,0x32,0x3b,0x0a,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x2b,0x3d,0x67,0x6c,0x6f,0x62,0x61, + 0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x28,0x45,0x4e,0x54,0x52,0x4f,0x50,0x59,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x6c,0x6f, + 0x6e,0x67,0x29,0x29,0x3b,0x0a,0x52,0x5b,0x30,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x32,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b, + 0x33,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x34,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x35,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b,0x36,0x5d,0x3d,0x30,0x3b,0x0a,0x52,0x5b, + 0x37,0x5d,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x20,0x41,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62, + 0x61,0x6c,0x20,0x64,0x6f,0x75,0x62,0x6c,0x65,0x2a,0x29,0x28,0x52,0x2b,0x32,0x34,0x29,0x3b,0x0a,0x41,0x5b,0x30,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c, + 0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x41, + 0x5b,0x31,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e, + 0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x32,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65, + 0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x32,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x33,0x5d,0x3d,0x67,0x65,0x74,0x53, + 0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x33,0x5d, + 0x29,0x3b,0x0a,0x41,0x5b,0x34,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74, + 0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x34,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x35,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69, + 0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x35,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x36,0x5d,0x3d, + 0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61,0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70, + 0x79,0x5b,0x36,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x37,0x5d,0x3d,0x67,0x65,0x74,0x53,0x6d,0x61,0x6c,0x6c,0x50,0x6f,0x73,0x69,0x74,0x69,0x76,0x65,0x46,0x6c,0x6f,0x61, + 0x74,0x42,0x69,0x74,0x73,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x37,0x5d,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69, + 0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x38,0x5d,0x26,0x43,0x61,0x63,0x68,0x65,0x4c, + 0x69,0x6e,0x65,0x41,0x6c,0x69,0x67,0x6e,0x4d,0x61,0x73,0x6b,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28, + 0x52,0x2b,0x31,0x36,0x29,0x29,0x5b,0x31,0x5d,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x61,0x64,0x64,0x72, + 0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x3d,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x32,0x5d,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c, + 0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x30,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73, + 0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x3e, + 0x3e,0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x31, + 0x5d,0x3d,0x32,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73, + 0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x3e,0x3e,0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x32,0x5d,0x3d,0x34,0x2b,0x28,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x73,0x26,0x31,0x29,0x3b,0x0a,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x20,0x3e,0x3e,0x3d,0x20,0x31,0x3b,0x0a,0x28,0x28, + 0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x37,0x29,0x29,0x5b,0x33,0x5d,0x3d,0x36,0x2b,0x28,0x61,0x64,0x64, + 0x72,0x65,0x73,0x73,0x52,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x73,0x26,0x31,0x29,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e, + 0x74,0x2a,0x29,0x28,0x52,0x2b,0x31,0x39,0x29,0x29,0x5b,0x30,0x5d,0x3d,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x33,0x5d,0x26,0x44,0x61,0x74,0x61,0x73, + 0x65,0x74,0x45,0x78,0x74,0x72,0x61,0x49,0x74,0x65,0x6d,0x73,0x29,0x2a,0x43,0x61,0x63,0x68,0x65,0x4c,0x69,0x6e,0x65,0x53,0x69,0x7a,0x65,0x3b,0x0a,0x52,0x5b,0x32, + 0x30,0x5d,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x34,0x5d,0x29,0x3b,0x0a,0x52,0x5b, + 0x32,0x31,0x5d,0x3d,0x67,0x65,0x74,0x46,0x6c,0x6f,0x61,0x74,0x4d,0x61,0x73,0x6b,0x28,0x65,0x6e,0x74,0x72,0x6f,0x70,0x79,0x5b,0x31,0x35,0x5d,0x29,0x3b,0x0a,0x7d, + 0x0a,0x00 }; } // namespace xmrig diff --git a/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.cpp b/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.cpp new file mode 100644 index 00000000..6b512854 --- /dev/null +++ b/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.cpp @@ -0,0 +1,58 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h" +#include "backend/opencl/wrappers/OclLib.h" + + +void xmrig::Blake2bInitialHashDoubleKernel::enqueue(cl_command_queue queue, size_t threads) +{ + const size_t gthreads = threads; + static const size_t lthreads = 64; + + enqueueNDRange(queue, 1, nullptr, >hreads, <hreads); +} + + +// __kernel void blake2b_initial_hash_double(__global void *out, __global const void* blockTemplate, uint blockTemplateSize, uint start_nonce) +void xmrig::Blake2bInitialHashDoubleKernel::setArgs(cl_mem out, cl_mem blockTemplate) +{ + setArg(0, sizeof(cl_mem), &out); + setArg(1, sizeof(cl_mem), &blockTemplate); +} + + +void xmrig::Blake2bInitialHashDoubleKernel::setBlobSize(size_t size) +{ + const uint32_t s = size; + + setArg(2, sizeof(uint32_t), &s); +} + + +void xmrig::Blake2bInitialHashDoubleKernel::setNonce(uint32_t nonce) +{ + setArg(3, sizeof(uint32_t), &nonce); +} diff --git a/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h b/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h new file mode 100644 index 00000000..fe7d8610 --- /dev/null +++ b/src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_BLAKE2BINITIALHASHDOUBLEKERNEL_H +#define XMRIG_BLAKE2BINITIALHASHDOUBLEKERNEL_H + + +#include "backend/opencl/wrappers/OclKernel.h" + + +namespace xmrig { + + +class Blake2bInitialHashDoubleKernel : public OclKernel +{ +public: + inline Blake2bInitialHashDoubleKernel(cl_program program) : OclKernel(program, "blake2b_initial_hash_double") {} + + void enqueue(cl_command_queue queue, size_t threads); + void setArgs(cl_mem out, cl_mem blockTemplate); + void setBlobSize(size_t size); + void setNonce(uint32_t nonce); +}; + + +} // namespace xmrig + + +#endif /* XMRIG_BLAKE2BINITIALHASHDOUBLEKERNEL_H */ diff --git a/src/backend/opencl/opencl.cmake b/src/backend/opencl/opencl.cmake index 84912c18..b32de797 100644 --- a/src/backend/opencl/opencl.cmake +++ b/src/backend/opencl/opencl.cmake @@ -80,6 +80,7 @@ if (WITH_OPENCL) if (WITH_RANDOMX) list(APPEND HEADERS_BACKEND_OPENCL src/backend/opencl/kernels/rx/Blake2bHashRegistersKernel.h + src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h src/backend/opencl/kernels/rx/Blake2bInitialHashKernel.h src/backend/opencl/kernels/rx/ExecuteVmKernel.h src/backend/opencl/kernels/rx/FillAesKernel.h @@ -96,6 +97,7 @@ if (WITH_OPENCL) list(APPEND SOURCES_BACKEND_OPENCL src/backend/opencl/generators/ocl_generic_rx_generator.cpp src/backend/opencl/kernels/rx/Blake2bHashRegistersKernel.cpp + src/backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.cpp src/backend/opencl/kernels/rx/Blake2bInitialHashKernel.cpp src/backend/opencl/kernels/rx/ExecuteVmKernel.cpp src/backend/opencl/kernels/rx/FillAesKernel.cpp diff --git a/src/backend/opencl/runners/OclRxBaseRunner.cpp b/src/backend/opencl/runners/OclRxBaseRunner.cpp index c991b0c4..4f633104 100644 --- a/src/backend/opencl/runners/OclRxBaseRunner.cpp +++ b/src/backend/opencl/runners/OclRxBaseRunner.cpp @@ -25,6 +25,7 @@ #include "backend/opencl/runners/OclRxBaseRunner.h" #include "backend/opencl/kernels/rx/Blake2bHashRegistersKernel.h" #include "backend/opencl/kernels/rx/Blake2bInitialHashKernel.h" +#include "backend/opencl/kernels/rx/Blake2bInitialHashDoubleKernel.h" #include "backend/opencl/kernels/rx/FillAesKernel.h" #include "backend/opencl/kernels/rx/FindSharesKernel.h" #include "backend/opencl/kernels/rx/HashAesKernel.h" @@ -71,6 +72,7 @@ xmrig::OclRxBaseRunner::~OclRxBaseRunner() delete m_fillAes4Rx4_entropy; delete m_hashAes1Rx4; delete m_blake2b_initial_hash; + delete m_blake2b_initial_hash_double; delete m_blake2b_hash_registers_32; delete m_blake2b_hash_registers_64; delete m_find_shares; @@ -87,12 +89,28 @@ void xmrig::OclRxBaseRunner::run(uint32_t nonce, uint32_t *hashOutput) { static const uint32_t zero = 0; - m_blake2b_initial_hash->setNonce(nonce); + if (m_jobSize <= 128) { + m_blake2b_initial_hash->setNonce(nonce); + } + else if (m_jobSize <= 256) { + m_blake2b_initial_hash_double->setNonce(nonce); + } + else { + hashOutput[0xFF] = 0; + return; + } + m_find_shares->setNonce(nonce); enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero); - m_blake2b_initial_hash->enqueue(m_queue, m_intensity); + if (m_jobSize <= 128) { + m_blake2b_initial_hash->enqueue(m_queue, m_intensity); + } + else { + m_blake2b_initial_hash_double->enqueue(m_queue, m_intensity); + } + m_fillAes1Rx4_scratchpad->enqueue(m_queue, m_intensity); const uint32_t programCount = RxAlgo::programCount(m_algorithm); @@ -134,7 +152,11 @@ void xmrig::OclRxBaseRunner::set(const Job &job, uint8_t *blob) enqueueWriteBuffer(m_input, CL_TRUE, 0, Job::kMaxBlobSize, blob); + m_jobSize = job.size(); + m_blake2b_initial_hash->setBlobSize(job.size()); + m_blake2b_initial_hash_double->setBlobSize(job.size()); + m_find_shares->setTarget(job.target()); } @@ -166,6 +188,9 @@ void xmrig::OclRxBaseRunner::build() m_blake2b_initial_hash = new Blake2bInitialHashKernel(m_program); m_blake2b_initial_hash->setArgs(m_hashes, m_input); + m_blake2b_initial_hash_double = new Blake2bInitialHashDoubleKernel(m_program); + m_blake2b_initial_hash_double->setArgs(m_hashes, m_input); + m_blake2b_hash_registers_32 = new Blake2bHashRegistersKernel(m_program, "blake2b_hash_registers_32"); m_blake2b_hash_registers_64 = new Blake2bHashRegistersKernel(m_program, "blake2b_hash_registers_64"); diff --git a/src/backend/opencl/runners/OclRxBaseRunner.h b/src/backend/opencl/runners/OclRxBaseRunner.h index f0d594c8..76b66e1c 100644 --- a/src/backend/opencl/runners/OclRxBaseRunner.h +++ b/src/backend/opencl/runners/OclRxBaseRunner.h @@ -35,6 +35,7 @@ namespace xmrig { class Blake2bHashRegistersKernel; class Blake2bInitialHashKernel; +class Blake2bInitialHashDoubleKernel; class FillAesKernel; class FindSharesKernel; class HashAesKernel; @@ -58,21 +59,24 @@ protected: protected: virtual void execute(uint32_t iteration) = 0; - Blake2bHashRegistersKernel *m_blake2b_hash_registers_32 = nullptr; - Blake2bHashRegistersKernel *m_blake2b_hash_registers_64 = nullptr; - Blake2bInitialHashKernel *m_blake2b_initial_hash = nullptr; + Blake2bHashRegistersKernel *m_blake2b_hash_registers_32 = nullptr; + Blake2bHashRegistersKernel *m_blake2b_hash_registers_64 = nullptr; + Blake2bInitialHashKernel *m_blake2b_initial_hash = nullptr; + Blake2bInitialHashDoubleKernel *m_blake2b_initial_hash_double = nullptr; Buffer m_seed; - cl_mem m_dataset = nullptr; - cl_mem m_entropy = nullptr; - cl_mem m_hashes = nullptr; - cl_mem m_rounding = nullptr; - cl_mem m_scratchpads = nullptr; - FillAesKernel *m_fillAes1Rx4_scratchpad = nullptr; - FillAesKernel *m_fillAes4Rx4_entropy = nullptr; - FindSharesKernel *m_find_shares = nullptr; - HashAesKernel *m_hashAes1Rx4 = nullptr; - uint32_t m_gcn_version = 12; - uint32_t m_worksize = 8; + cl_mem m_dataset = nullptr; + cl_mem m_entropy = nullptr; + cl_mem m_hashes = nullptr; + cl_mem m_rounding = nullptr; + cl_mem m_scratchpads = nullptr; + FillAesKernel *m_fillAes1Rx4_scratchpad = nullptr; + FillAesKernel *m_fillAes4Rx4_entropy = nullptr; + FindSharesKernel *m_find_shares = nullptr; + HashAesKernel *m_hashAes1Rx4 = nullptr; + uint32_t m_gcn_version = 12; + uint32_t m_worksize = 8; + + size_t m_jobSize = 0; }; From 8afd4d5f2f6959c98e6115119e06bcf60797836d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jan 2024 00:31:16 +0700 Subject: [PATCH 64/87] Cleanup. --- src/base/net/stratum/Pool.h | 12 ++++++------ src/core/config/usage.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index a8beee62..a78eb6bb 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 Howard Chu - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ public: static const char *kCoin; static const char *kDaemon; static const char *kDaemonPollInterval; - static const char* kDaemonJobTimeout; + static const char *kDaemonJobTimeout; static const char *kEnabled; static const char *kFingerprint; static const char *kKeepalive; @@ -70,11 +70,11 @@ public: static const char *kSOCKS5; static const char *kSubmitToOrigin; static const char *kTls; - static const char* kSni; + static const char *kSni; static const char *kUrl; static const char *kUser; - static const char* kSpendSecretKey; - static const char* kDaemonZMQPort; + static const char *kSpendSecretKey; + static const char *kDaemonZMQPort; static const char *kNicehashHost; constexpr static int kKeepAliveTimeout = 60; diff --git a/src/core/config/usage.h b/src/core/config/usage.h index eb7a9ec7..53a8e58c 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -4,8 +4,8 @@ * Copyright (c) 2014 Lucas Jones * Copyright (c) 2014-2016 Wolf9466 * Copyright (c) 2016 Jay D Dee - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,7 +64,7 @@ static inline const std::string &usage() # ifdef XMRIG_FEATURE_HTTP u += " --daemon use daemon RPC instead of pool for solo mining\n"; - u += " --daemon-zmq-port daemon's zmq-pub port number (only use it if daemon has it enabled)\n"; + u += " --daemon-zmq-port=N daemon's zmq-pub port number (only use it if daemon has it enabled)\n"; u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"; u += " --daemon-job-timeout=N daemon job timeout in milliseconds (default: 15000)\n"; u += " --self-select=URL self-select block templates from URL\n"; From daa63284184176c447f344c75272e89ef07cfebf Mon Sep 17 00:00:00 2001 From: "Dave Walker (Daviey)" Date: Sun, 11 Feb 2024 17:52:36 +0000 Subject: [PATCH 65/87] Fix segfault in HTTP API rebind Previously with HTTP API enabled on brenchmarking run, it is possible to cause a segfault due to an issue handling the m_httpd pointer and rebinding. - Initialize m_httpd to nullptr to indicate when it's not in use. - Safely delete m_httpd in Api's destructor to prevent use-after-free issues. - Add checks to ensure m_httpd is not nullptr before usage in start, stop, and tick methods. - Log errors for HTTP server start failures to aid in debugging. Fixes MoneroOcean/xmrig#120 Signed-off-by: Dave Walker (Daviey) --- src/base/api/Api.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index ea78c35e..e0907a84 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -39,6 +39,7 @@ #include +#include namespace xmrig { @@ -80,7 +81,8 @@ static rapidjson::Value getResources(rapidjson::Document &doc) xmrig::Api::Api(Base *base) : m_base(base), - m_timestamp(Chrono::currentMSecsSinceEpoch()) + m_timestamp(Chrono::currentMSecsSinceEpoch()), + m_httpd(nullptr) { base->addListener(this); @@ -91,7 +93,11 @@ xmrig::Api::Api(Base *base) : xmrig::Api::~Api() { # ifdef XMRIG_FEATURE_HTTP - delete m_httpd; + if (m_httpd) { + m_httpd->stop(); + delete m_httpd; + m_httpd = nullptr; // Ensure the pointer is set to nullptr after deletion + } # endif } @@ -109,8 +115,14 @@ void xmrig::Api::start() genWorkerId(m_base->config()->apiWorkerId()); # ifdef XMRIG_FEATURE_HTTP - m_httpd = new Httpd(m_base); - m_httpd->start(); + if (!m_httpd) { + m_httpd = new Httpd(m_base); + if (!m_httpd->start()) { + std::cerr << "HTTP server failed to start." << std::endl; + delete m_httpd; // Properly handle failure to start + m_httpd = nullptr; + } + } # endif } @@ -118,7 +130,9 @@ void xmrig::Api::start() void xmrig::Api::stop() { # ifdef XMRIG_FEATURE_HTTP - m_httpd->stop(); + if (m_httpd) { + m_httpd->stop(); + } # endif } @@ -126,13 +140,15 @@ void xmrig::Api::stop() void xmrig::Api::tick() { # ifdef XMRIG_FEATURE_HTTP - if (m_httpd->isBound() || !m_base->config()->http().isEnabled()) { + if (!m_httpd || !m_base->config()->http().isEnabled() || m_httpd->isBound()) { return; } if (++m_ticks % 10 == 0) { m_ticks = 0; - m_httpd->start(); + if (m_httpd) { + m_httpd->start(); + } } # endif } From 7b6ce598211d96d3f0b3e3575a32b66c819b8846 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 22 Feb 2024 03:26:41 +0700 Subject: [PATCH 66/87] Update CHANGELOG.md. --- CHANGELOG.md | 5 +++++ src/version.h | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48c52131..bf89deb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v6.21.1 +- [#3391](https://github.com/xmrig/xmrig/pull/3391) Added support for townforge (monero fork using randomx). +- [#3399](https://github.com/xmrig/xmrig/pull/3399) Fixed Zephyr mining (OpenCL). +- [#3420](https://github.com/xmrig/xmrig/pull/3420) Fixed segfault in HTTP API rebind. + # v6.21.0 - [#3302](https://github.com/xmrig/xmrig/pull/3302) [#3312](https://github.com/xmrig/xmrig/pull/3312) Enabled keepalive for Windows (>= Vista). - [#3320](https://github.com/xmrig/xmrig/pull/3320) Added "built for OS/architecture/bits" to "ABOUT". diff --git a/src/version.h b/src/version.h index a2a2e13d..a753ee06 100644 --- a/src/version.h +++ b/src/version.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2023 SChernykh - * Copyright (c) 2016-2023 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ #define APP_VERSION "6.21.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" -#define APP_COPYRIGHT "Copyright (C) 2016-2023 xmrig.com" +#define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 6 From a5aa2c90425c0baaf7bfdd118bbedb13e9267c26 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 25 Feb 2024 22:26:52 +0700 Subject: [PATCH 67/87] v6.21.1 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index a753ee06..1578882e 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.1-dev" +#define APP_VERSION "6.21.1" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" From f9c4c572164eb50129b0b541143ae5e5a409c3c1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 25 Feb 2024 23:00:45 +0700 Subject: [PATCH 68/87] v6.21.2-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 1578882e..f22dcd5b 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.1" +#define APP_VERSION "6.21.2-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 21 -#define APP_VER_PATCH 1 +#define APP_VER_PATCH 2 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From b49197f8088fa594e4e9a1794f3f189b1d782b47 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Tue, 27 Feb 2024 23:39:23 +0100 Subject: [PATCH 69/87] Stratum: better check of the login response --- src/base/net/stratum/Client.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 50e35bcc..68122f93 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -609,6 +609,11 @@ bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code) parseExtensions(result); + if (!result.HasMember("job")) { + *code = 2; + return false; + } + const bool rc = parseJob(result["job"], code); m_jobs = 0; From c9b9ef51ee6b376d629264ac4056fc111c7b8b40 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 29 Feb 2024 09:38:47 +0700 Subject: [PATCH 70/87] #2800 Fixed donation with ghostrider algorithm for builds without KawPow algorithm. --- src/base/net/stratum/Client.cpp | 13 ++++--------- src/net/strategies/DonateStrategy.cpp | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 68122f93..54246e72 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 jtgrassie - * Copyright (c) 2018-2023 SChernykh - * Copyright (c) 2016-2023 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -609,12 +609,7 @@ bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code) parseExtensions(result); - if (!result.HasMember("job")) { - *code = 2; - return false; - } - - const bool rc = parseJob(result["job"], code); + const bool rc = parseJob(Json::getObject(result, "job"), code); m_jobs = 0; return rc; @@ -849,7 +844,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co m_listener->onLoginSuccess(this); if (m_job.isValid()) { - m_listener->onJobReceived(this, m_job, result["job"]); + m_listener->onJobReceived(this, m_job, Json::getObject(result, "job")); } return; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 03447a01..1f647ae4 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -63,7 +63,7 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener keccak(reinterpret_cast(user.data()), user.size(), hash); Cvt::toHex(m_userId, sizeof(m_userId), hash, 32); -# ifdef XMRIG_ALGO_KAWPOW +# if defined XMRIG_ALGO_KAWPOW || defined XMRIG_ALGO_GHOSTRIDER constexpr Pool::Mode mode = Pool::MODE_AUTO_ETH; # else constexpr Pool::Mode mode = Pool::MODE_POOL; From 48fa095e3e42f41a48367f87fcb0824b8fc36e1e Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:31:16 +0100 Subject: [PATCH 71/87] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6404cef2..6061aeec 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -17,6 +17,9 @@ Steps to reproduce the behavior. A clear and concise description of what you expected to happen. **Required data** + - XMRig version + - Either the exact link to a release you downloaded from https://github.com/xmrig/xmrig/releases + - Or the exact command lines that you used to build XMRig - Miner log as text or screenshot - Config file or command line (without wallets) - OS: [e.g. Windows] From 688d4f5ee16fab4d7153c0c92005925b4dd0f008 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Mon, 4 Mar 2024 08:45:22 +0100 Subject: [PATCH 72/87] Thread-safe FileLogWriter --- src/base/io/log/FileLogWriter.cpp | 74 +++++++++++++++++++++++++------ src/base/io/log/FileLogWriter.h | 18 +++++++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/base/io/log/FileLogWriter.cpp b/src/base/io/log/FileLogWriter.cpp index b41f7f39..a449dc9a 100644 --- a/src/base/io/log/FileLogWriter.cpp +++ b/src/base/io/log/FileLogWriter.cpp @@ -22,7 +22,6 @@ #include -#include namespace xmrig { @@ -40,6 +39,32 @@ static void fsWriteCallback(uv_fs_t *req) } // namespace xmrig +xmrig::FileLogWriter::FileLogWriter() +{ + init(); +} + +xmrig::FileLogWriter::FileLogWriter(const char* fileName) +{ + init(); + open(fileName); +} + +xmrig::FileLogWriter::~FileLogWriter() +{ + uv_close(reinterpret_cast(&m_flushAsync), nullptr); + + uv_mutex_destroy(&m_buffersLock); +} + +void xmrig::FileLogWriter::init() +{ + uv_mutex_init(&m_buffersLock); + + uv_async_init(uv_default_loop(), &m_flushAsync, on_flush); + m_flushAsync.data = this; +} + bool xmrig::FileLogWriter::open(const char *fileName) { assert(fileName != nullptr); @@ -77,11 +102,12 @@ bool xmrig::FileLogWriter::write(const char *data, size_t size) uv_buf_t buf = uv_buf_init(new char[size], size); memcpy(buf.base, data, size); - auto req = new uv_fs_t; - req->data = buf.base; + uv_mutex_lock(&m_buffersLock); - uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, m_pos, fsWriteCallback); - m_pos += size; + m_buffers.emplace_back(buf); + uv_async_send(&m_flushAsync); + + uv_mutex_unlock(&m_buffersLock); return true; } @@ -89,18 +115,38 @@ bool xmrig::FileLogWriter::write(const char *data, size_t size) bool xmrig::FileLogWriter::writeLine(const char *data, size_t size) { - const uv_buf_t buf[2] = { - uv_buf_init(new char[size], size), - uv_buf_init(const_cast(m_endl), sizeof(m_endl) - 1) - }; + if (!isOpen()) { + return false; + } - memcpy(buf[0].base, data, size); + constexpr size_t N = sizeof(m_endl) - 1; - auto req = new uv_fs_t; - req->data = buf[0].base; + uv_buf_t buf = uv_buf_init(new char[size + N], size + N); + memcpy(buf.base, data, size); + memcpy(buf.base + size, m_endl, N); - uv_fs_write(uv_default_loop(), req, m_file, buf, 2, m_pos, fsWriteCallback); - m_pos += (buf[0].len + buf[1].len); + uv_mutex_lock(&m_buffersLock); + + m_buffers.emplace_back(buf); + uv_async_send(&m_flushAsync); + + uv_mutex_unlock(&m_buffersLock); return true; } + +void xmrig::FileLogWriter::flush() +{ + uv_mutex_lock(&m_buffersLock); + + for (uv_buf_t buf : m_buffers) { + uv_fs_t* req = new uv_fs_t; + req->data = buf.base; + + uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, m_pos, fsWriteCallback); + m_pos += buf.len; + } + m_buffers.clear(); + + uv_mutex_unlock(&m_buffersLock); +} diff --git a/src/base/io/log/FileLogWriter.h b/src/base/io/log/FileLogWriter.h index f3606aa3..66b8a13c 100644 --- a/src/base/io/log/FileLogWriter.h +++ b/src/base/io/log/FileLogWriter.h @@ -22,6 +22,8 @@ #include #include +#include +#include namespace xmrig { @@ -30,8 +32,10 @@ namespace xmrig { class FileLogWriter { public: - FileLogWriter() = default; - FileLogWriter(const char *fileName) { open(fileName); } + FileLogWriter(); + FileLogWriter(const char* fileName); + + ~FileLogWriter(); inline bool isOpen() const { return m_file >= 0; } inline int64_t pos() const { return m_pos; } @@ -49,6 +53,16 @@ private: int m_file = -1; int64_t m_pos = 0; + + uv_mutex_t m_buffersLock; + std::vector m_buffers; + + uv_async_t m_flushAsync; + + void init(); + + static void on_flush(uv_async_t* async) { reinterpret_cast(async->data)->flush(); } + void flush(); }; From 08c43b7e586299bf083d3b78c2132e26fd4a69b7 Mon Sep 17 00:00:00 2001 From: goodmost Date: Tue, 19 Mar 2024 23:19:36 +0800 Subject: [PATCH 73/87] chore: remove repetitive words Signed-off-by: goodmost --- doc/CHANGELOG_OLD.md | 2 +- src/3rdparty/epee/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/CHANGELOG_OLD.md b/doc/CHANGELOG_OLD.md index 70059190..a799cb38 100644 --- a/doc/CHANGELOG_OLD.md +++ b/doc/CHANGELOG_OLD.md @@ -256,7 +256,7 @@ # v2.8.0 - **[#753](https://github.com/xmrig/xmrig/issues/753) Added new algorithm [CryptoNight variant 2](https://github.com/xmrig/xmrig/issues/753) for Monero fork, thanks [@SChernykh](https://github.com/SChernykh).** - - Added global and per thread option `"asm"` and and command line equivalent. + - Added global and per thread option `"asm"` and command line equivalent. - **[#758](https://github.com/xmrig/xmrig/issues/758) Added SSL/TLS support for secure connections to pools.** - Added per pool options `"tls"` and `"tls-fingerprint"` and command line equivalents. - [#767](https://github.com/xmrig/xmrig/issues/767) Added config autosave feature, same with GPU miners. diff --git a/src/3rdparty/epee/README.md b/src/3rdparty/epee/README.md index 57e0efb1..2f06fe06 100644 --- a/src/3rdparty/epee/README.md +++ b/src/3rdparty/epee/README.md @@ -1 +1 @@ -epee - is a small library of helpers, wrappers, tools and and so on, used to make my life easier. +epee - is a small library of helpers, wrappers, tools and so on, used to make my life easier. From 1fb5be6c1d292c14f0d2562f6cb034087b68e9ce Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 20 Mar 2024 00:24:46 +0700 Subject: [PATCH 74/87] Update deps. --- scripts/build.hwloc.sh | 2 +- scripts/build.openssl3.sh | 2 +- scripts/build.uv.sh | 6 +++--- scripts/build_deps.sh | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build.hwloc.sh b/scripts/build.hwloc.sh index 223c5fb0..077d87b8 100755 --- a/scripts/build.hwloc.sh +++ b/scripts/build.hwloc.sh @@ -1,7 +1,7 @@ #!/bin/bash -e HWLOC_VERSION_MAJOR="2" -HWLOC_VERSION_MINOR="9" +HWLOC_VERSION_MINOR="10" HWLOC_VERSION_PATCH="0" HWLOC_VERSION="${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}.${HWLOC_VERSION_PATCH}" diff --git a/scripts/build.openssl3.sh b/scripts/build.openssl3.sh index ffd1b953..70e989f7 100755 --- a/scripts/build.openssl3.sh +++ b/scripts/build.openssl3.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -OPENSSL_VERSION="3.0.7" +OPENSSL_VERSION="3.0.13" mkdir -p deps mkdir -p deps/include diff --git a/scripts/build.uv.sh b/scripts/build.uv.sh index 3ee766a7..3a016a2a 100755 --- a/scripts/build.uv.sh +++ b/scripts/build.uv.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -UV_VERSION="1.44.2" +UV_VERSION="1.48.0" mkdir -p deps mkdir -p deps/include @@ -8,10 +8,10 @@ mkdir -p deps/lib mkdir -p build && cd build -wget https://github.com/libuv/libuv/archive/v${UV_VERSION}.tar.gz -O v${UV_VERSION}.tar.gz +wget https://dist.libuv.org/dist/v${UV_VERSION}/libuv-v${UV_VERSION}.tar.gz -O v${UV_VERSION}.tar.gz tar -xzf v${UV_VERSION}.tar.gz -cd libuv-${UV_VERSION} +cd libuv-v${UV_VERSION} sh autogen.sh ./configure --disable-shared make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index e3efbf23..c294f969 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -2,4 +2,4 @@ ./build.uv.sh ./build.hwloc.sh -./build.openssl.sh \ No newline at end of file +./build.openssl3.sh \ No newline at end of file From 5552e1f864b290d9b9674dbdf5f5bb8c21744dc7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 21 Mar 2024 02:13:01 +0700 Subject: [PATCH 75/87] Fix scripts for systems without bash. --- scripts/build.hwloc.sh | 2 +- scripts/build.hwloc1.sh | 2 +- scripts/build.libressl.sh | 2 +- scripts/build.openssl.sh | 2 +- scripts/build.openssl3.sh | 2 +- scripts/build.uv.sh | 2 +- scripts/build_deps.sh | 2 +- scripts/enable_1gb_pages.sh | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/build.hwloc.sh b/scripts/build.hwloc.sh index 077d87b8..db85fb6f 100755 --- a/scripts/build.hwloc.sh +++ b/scripts/build.hwloc.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e HWLOC_VERSION_MAJOR="2" HWLOC_VERSION_MINOR="10" diff --git a/scripts/build.hwloc1.sh b/scripts/build.hwloc1.sh index f1afc285..82572743 100755 --- a/scripts/build.hwloc1.sh +++ b/scripts/build.hwloc1.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e HWLOC_VERSION="1.11.13" diff --git a/scripts/build.libressl.sh b/scripts/build.libressl.sh index d32c04fa..6dde9faa 100755 --- a/scripts/build.libressl.sh +++ b/scripts/build.libressl.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e LIBRESSL_VERSION="3.5.2" diff --git a/scripts/build.openssl.sh b/scripts/build.openssl.sh index a89b281f..722e11b5 100755 --- a/scripts/build.openssl.sh +++ b/scripts/build.openssl.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e OPENSSL_VERSION="1.1.1s" diff --git a/scripts/build.openssl3.sh b/scripts/build.openssl3.sh index 70e989f7..e42fcac0 100755 --- a/scripts/build.openssl3.sh +++ b/scripts/build.openssl3.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e OPENSSL_VERSION="3.0.13" diff --git a/scripts/build.uv.sh b/scripts/build.uv.sh index 3a016a2a..ca052f7a 100755 --- a/scripts/build.uv.sh +++ b/scripts/build.uv.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e UV_VERSION="1.48.0" diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index c294f969..d244665f 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e ./build.uv.sh ./build.hwloc.sh diff --git a/scripts/enable_1gb_pages.sh b/scripts/enable_1gb_pages.sh index 16d889f1..a1fb4c61 100755 --- a/scripts/enable_1gb_pages.sh +++ b/scripts/enable_1gb_pages.sh @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e # https://xmrig.com/docs/miner/hugepages#onegb-huge-pages From f6c50b5393ce1ba8596336dc867ec8eefcd9d7a2 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:24:02 +0100 Subject: [PATCH 76/87] Fix RandomX crash when compiled with fortify_source --- src/crypto/randomx/jit_compiler_a64.cpp | 2 +- src/crypto/randomx/jit_compiler_a64.hpp | 2 +- src/crypto/randomx/jit_compiler_x86.cpp | 2 +- src/crypto/randomx/jit_compiler_x86.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 05dac9f7..4bfe157e 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -1078,6 +1078,6 @@ void JitCompilerA64::h_NOP(Instruction& instr, uint32_t& codePos) { } -InstructionGeneratorA64 JitCompilerA64::engine[256] = {}; +InstructionGeneratorA64 JitCompilerA64::engine[257] = {}; } diff --git a/src/crypto/randomx/jit_compiler_a64.hpp b/src/crypto/randomx/jit_compiler_a64.hpp index 32ff5166..15c90af8 100644 --- a/src/crypto/randomx/jit_compiler_a64.hpp +++ b/src/crypto/randomx/jit_compiler_a64.hpp @@ -74,7 +74,7 @@ namespace randomx { void enableWriting() const; void enableExecution() const; - static InstructionGeneratorA64 engine[256]; + static InstructionGeneratorA64 engine[257]; private: const bool hugePages; diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 7f9fb3b6..78ab8b58 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -1443,6 +1443,6 @@ namespace randomx { emitByte(0x90, code, codePos); } - alignas(64) InstructionGeneratorX86 JitCompilerX86::engine[256] = {}; + alignas(64) InstructionGeneratorX86 JitCompilerX86::engine[257] = {}; } diff --git a/src/crypto/randomx/jit_compiler_x86.hpp b/src/crypto/randomx/jit_compiler_x86.hpp index 15261922..11106b2f 100644 --- a/src/crypto/randomx/jit_compiler_x86.hpp +++ b/src/crypto/randomx/jit_compiler_x86.hpp @@ -81,7 +81,7 @@ namespace randomx { void enableWriting() const; void enableExecution() const; - alignas(64) static InstructionGeneratorX86 engine[256]; + alignas(64) static InstructionGeneratorX86 engine[257]; private: int registerUsage[RegistersCount] = {}; From b8e4eaac87e8325647258dec58cd9279284532cc Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 21 Mar 2024 21:03:35 +0700 Subject: [PATCH 77/87] Fix rapidjson assert. --- src/base/net/http/HttpApiResponse.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/base/net/http/HttpApiResponse.cpp b/src/base/net/http/HttpApiResponse.cpp index e6758df9..3ee38a09 100644 --- a/src/base/net/http/HttpApiResponse.cpp +++ b/src/base/net/http/HttpApiResponse.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2014-2019 heapwolf - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "base/net/http/HttpApiResponse.h" #include "3rdparty/rapidjson/prettywriter.h" #include "3rdparty/rapidjson/stringbuffer.h" @@ -65,7 +64,7 @@ void xmrig::HttpApiResponse::end() } } - if (!m_doc.MemberCount()) { + if (m_doc.IsObject() && m_doc.ObjectEmpty()) { return HttpResponse::end(); } From 850b43c0796e262809cbb7aaaf740331179f2a74 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 22 Mar 2024 01:22:54 +0700 Subject: [PATCH 78/87] Fix build with recent libuv. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d37734ac..acf66cc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,7 +162,7 @@ if (XMRIG_OS_WIN) src/crypto/common/VirtualMemory_win.cpp ) - set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) + set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv dbghelp) elseif (XMRIG_OS_APPLE) list(APPEND SOURCES_OS src/App_unix.cpp From 7a85257ad4dd91565d53be4cfbe76ccf0045af38 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 22 Mar 2024 18:14:39 +0700 Subject: [PATCH 79/87] Update hwloc for MSVC builds. --- CMakeLists.txt | 2 +- src/3rdparty/argon2/CMakeLists.txt | 2 +- src/3rdparty/hwloc/CMakeLists.txt | 2 +- src/3rdparty/hwloc/NEWS | 107 +- src/3rdparty/hwloc/README | 496 +++++++- src/3rdparty/hwloc/VERSION | 7 +- .../hwloc/include/hwloc/autogen/config.h | 6 +- src/3rdparty/hwloc/include/hwloc/bitmap.h | 51 +- src/3rdparty/hwloc/include/hwloc/cuda.h | 8 +- src/3rdparty/hwloc/include/hwloc/cudart.h | 8 +- src/3rdparty/hwloc/include/hwloc/diff.h | 17 +- src/3rdparty/hwloc/include/hwloc/distances.h | 37 +- src/3rdparty/hwloc/include/hwloc/export.h | 16 +- src/3rdparty/hwloc/include/hwloc/gl.h | 5 +- .../hwloc/include/hwloc/glibc-sched.h | 13 +- src/3rdparty/hwloc/include/hwloc/helper.h | 1039 +++++++++-------- src/3rdparty/hwloc/include/hwloc/levelzero.h | 10 +- .../hwloc/include/hwloc/linux-libnuma.h | 34 +- src/3rdparty/hwloc/include/hwloc/linux.h | 10 +- src/3rdparty/hwloc/include/hwloc/memattrs.h | 44 +- src/3rdparty/hwloc/include/hwloc/nvml.h | 5 +- src/3rdparty/hwloc/include/hwloc/opencl.h | 8 +- .../hwloc/include/hwloc/openfabrics-verbs.h | 5 +- src/3rdparty/hwloc/include/hwloc/plugins.h | 2 +- src/3rdparty/hwloc/include/hwloc/rename.h | 1 + src/3rdparty/hwloc/include/hwloc/rsmi.h | 5 +- src/3rdparty/hwloc/include/hwloc/shmem.h | 17 +- src/3rdparty/hwloc/include/private/netloc.h | 578 --------- src/3rdparty/hwloc/include/private/private.h | 11 +- src/3rdparty/hwloc/include/private/xml.h | 8 +- src/3rdparty/hwloc/src/components.c | 3 +- src/3rdparty/hwloc/src/diff.c | 26 +- src/3rdparty/hwloc/src/memattrs.c | 758 +++++++++--- src/3rdparty/hwloc/src/shmem.c | 11 +- src/3rdparty/hwloc/src/topology-synthetic.c | 154 ++- src/3rdparty/hwloc/src/topology-windows.c | 26 +- src/3rdparty/hwloc/src/topology-x86.c | 308 +++-- .../hwloc/src/topology-xml-nolibxml.c | 9 +- src/3rdparty/hwloc/src/topology-xml.c | 77 +- src/3rdparty/hwloc/src/topology.c | 207 ++-- src/3rdparty/libethash/CMakeLists.txt | 2 +- src/crypto/ghostrider/CMakeLists.txt | 2 +- 42 files changed, 2554 insertions(+), 1583 deletions(-) delete mode 100644 src/3rdparty/hwloc/include/private/netloc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index acf66cc8..70d57d10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project(xmrig) option(WITH_HWLOC "Enable hwloc support" ON) diff --git a/src/3rdparty/argon2/CMakeLists.txt b/src/3rdparty/argon2/CMakeLists.txt index 7bbe716b..1ad977f0 100644 --- a/src/3rdparty/argon2/CMakeLists.txt +++ b/src/3rdparty/argon2/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project(argon2 C) set(CMAKE_C_STANDARD 99) diff --git a/src/3rdparty/hwloc/CMakeLists.txt b/src/3rdparty/hwloc/CMakeLists.txt index ef2ba72d..37b88cbb 100644 --- a/src/3rdparty/hwloc/CMakeLists.txt +++ b/src/3rdparty/hwloc/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project (hwloc C) include_directories(include) diff --git a/src/3rdparty/hwloc/NEWS b/src/3rdparty/hwloc/NEWS index 4ddcbf44..62cc687e 100644 --- a/src/3rdparty/hwloc/NEWS +++ b/src/3rdparty/hwloc/NEWS @@ -1,5 +1,5 @@ Copyright © 2009 CNRS -Copyright © 2009-2022 Inria. All rights reserved. +Copyright © 2009-2023 Inria. All rights reserved. Copyright © 2009-2013 Université Bordeaux Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. Copyright © 2020 Hewlett Packard Enterprise. All rights reserved. @@ -17,6 +17,103 @@ bug fixes (and other actions) for each version of hwloc since version 0.9. +Version 2.10.0 +-------------- +* Heterogeneous Memory core improvements + + Better heuristics to identify the subtype of memory such as HBM, + DRAM, NVM, CXL-DRAM, etc. + + Build memory tiers, i.e. sets of NUMA nodes with the same subtype + and similar performance. + - NUMA node tier ranks are exposed in the new MemoryTier info + attribute (starts from 0 for highest bandwidth tier).. + + See the new Heterogeneous Memory section in the documentation. +* API + + Add hwloc_topology_free_group_object() to discard a Group created + by hwloc_topology_alloc_group_object(). +* Linux backend + + Fix cpukinds on NVIDIA Grace to report identical cores even if they + actually have very small frequency differences. + Thanks to John C. Linford for the report. + + Add CXLDevice attributes to CXL DAX objects and NUMA nodes to show + which PCI device implements which window. + + Ignore buggy memory-side caches and memory attributes when fake NUMA + emulation is enabled on the Linux kernel command-line. + + Add more info attributes in MemoryModule Misc objects, + thanks to Zubiao Xiong for the patch. + + Get CPUModel and CPUFamily info attributes on LoongArch platforms. +* x86 backend + + Add support for new AMD CPUID leaf 0x80000026 for better detection + of Core Complex and Die on Zen4 processors. + + Improve Zhaoxin CPU topology detection. +* Tools + + Input locations and many command-line options (e.g. hwloc-calc -I -N -H, + lstopo --only) now accept filters such as "NUMA[HBM]" so that only + objects are that type and subtype are considered. + - NUMA[tier=1] is also accepted for selecting NUMA nodes depending + on their MemoryTier info attribute. + + Add --object-output to hwloc-calc to report the type as a prefix to + object indexes, e.g. Core:2 instead of 2 in the output of -I. + + hwloc-info --ancestor and --descendants now accepts kinds of objects + instead of single types. + - The new --first option only shows the first matching object. + + Add --children-of-pid to hwloc-ps to show a hierarchy of processes. + Thanks to Antoine Morvan for the suggestion. + + Add --misc-from to lstopo to add Misc objects described in a file. + - To be combined with the new hwloc-ps --lstopo-misc for a customizable + lstopo --top replacement. +* Misc + + lstopo may now configure the layout of memory object placed above, + for instance with --children-order memory:above:vert. + + Fix XML import from memory or stdin when using libxml2 2.12. + + Fix installation failures when configuring with --target, + thanks to Clement Foyer for the patch. + + Fix support for 128bit pointer architectures. + + Remove Netloc. + + +Version 2.9.3 +------------- +* Handle Linux glibc allocation errors in binding routines (CVE-2022-47022). +* Fix hwloc-calc when searching objects on heterogeneous memory platforms, + thanks to Antoine Morvan for the report. +* Fix hwloc_get_next_child() when there are some memory-side caches. +* Don't crash if the topology is empty because Linux cgroups are wrong. +* Improve some hwloc-bind warnings in case of command-line parsing errors. +* Many documentation improvements all over the place, including: + + hwloc_topology_restrict() and hwloc_topology_insert_group() may reorder + children, causing the logical indexes of objects to change. + + +Version 2.9.2 +------------- +* Don't forget L3i when defining filters for multiple levels of caches + with hwloc_topology_set_cache/icache_types_filter(). +* Fix object total_memory after hwloc_topology_insert_group_object(). +* Fix the (non-yet) exporting in synthetic description for complex memory + hierarchies with memory-side caches, etc. +* Fix some default size attributes when building synthetic topologies. +* Fix size units in hwloc-annotate. +* Improve bitmap reallocation error management in many functions. +* Documentation improvements: + + Better document return values of functions. + + Add "Error reporting" section (in hwloc.h and in the doxygen doc). + + Add FAQ entry "What may I disable to make hwloc faster?" + + Improve FAQ entries "Why is lstopo slow?" and + "I only need ..., why should I use hwloc?" + + Clarify how to deal with cpukinds in hwloc-calc and hwloc-bind + manpages. + + +Version 2.9.1 +------------- +* Don't forget to apply object type filters to "perflevel" caches detected + on recent Mac OS X releases, thanks to Michel Lesoinne for the report. +* Fix a failed assertion in hwloc_topology_restrict() when some NUMA nodes + are removed because of HWLOC_RESTRICT_FLAG_REMOVE_CPULESS but no PUs are. + Thanks to Mark Grondona for reporting the issue. +* Mark HPE Cray Slingshot NICs with subtype "Slingshot". + + Version 2.9.0 ------------- * Backends @@ -61,6 +158,14 @@ Version 2.8.0 file from the documentation. +Version 2.7.2 +------------- +* Fix a crash when LevelZero devices have multiple subdevices, + e.g. on PonteVecchio GPUs, thanks to Jonathan Peyton. +* Fix a leak when importing cpukinds from XML, + thanks to Hui Zhou. + + Version 2.7.1 ------------- * Workaround crashes when virtual machines report incoherent x86 CPUID diff --git a/src/3rdparty/hwloc/README b/src/3rdparty/hwloc/README index 43210e63..f2971d07 100644 --- a/src/3rdparty/hwloc/README +++ b/src/3rdparty/hwloc/README @@ -1,4 +1,8 @@ -Introduction +This is a truncated and poorly-formatted version of the documentation main page. +See https://www.open-mpi.org/projects/hwloc/doc/ for more. + + +hwloc Overview The Hardware Locality (hwloc) software project aims at easing the process of discovering hardware resources in parallel architectures. It offers @@ -8,66 +12,456 @@ high-performance computing (HPC) applications, but is also applicable to any project seeking to exploit code and/or data locality on modern computing platforms. -hwloc is actually made of two subprojects distributed together: +hwloc provides command line tools and a C API to obtain the hierarchical map of +key computing elements within a node, such as: NUMA memory nodes, shared +caches, processor packages, dies and cores, processing units (logical +processors or "threads") and even I/O devices. hwloc also gathers various +attributes such as cache and memory information, and is portable across a +variety of different operating systems and platforms. - * The original hwloc project for describing the internals of computing nodes. - It is described in details starting at section Hardware Locality (hwloc) - Introduction. - * The network-oriented companion called netloc (Network Locality), described - in details starting with section Network Locality (netloc). +hwloc primarily aims at helping high-performance computing (HPC) applications, +but is also applicable to any project seeking to exploit code and/or data +locality on modern computing platforms. -See also the Related pages tab above for links to other sections. +hwloc supports the following operating systems: -Netloc may be disabled, but the original hwloc cannot. Both hwloc and netloc -APIs are documented after these sections. + * Linux (with knowledge of cgroups and cpusets, memory targets/initiators, + etc.) on all supported hardware, including Intel Xeon Phi, ScaleMP vSMP, + and NumaScale NumaConnect. + * Solaris (with support for processor sets and logical domains) + * AIX + * Darwin / OS X + * FreeBSD and its variants (such as kFreeBSD/GNU) + * NetBSD + * HP-UX + * Microsoft Windows + * IBM BlueGene/Q Compute Node Kernel (CNK) -Installation +Since it uses standard Operating System information, hwloc's support is mostly +independant from the processor type (x86, powerpc, ...) and just relies on the +Operating System support. The main exception is BSD operating systems (NetBSD, +FreeBSD, etc.) because they do not provide support topology information, hence +hwloc uses an x86-only CPUID-based backend (which can be used for other OSes +too, see the Components and plugins section). -hwloc (https://www.open-mpi.org/projects/hwloc/) is available under the BSD -license. It is hosted as a sub-project of the overall Open MPI project (https:/ -/www.open-mpi.org/). Note that hwloc does not require any functionality from -Open MPI -- it is a wholly separate (and much smaller!) project and code base. -It just happens to be hosted as part of the overall Open MPI project. +To check whether hwloc works on a particular machine, just try to build it and +run lstopo or lstopo-no-graphics. If some things do not look right (e.g. bogus +or missing cache information), see Questions and Bugs. -Basic Installation +hwloc only reports the number of processors on unsupported operating systems; +no topology information is available. -Installation is the fairly common GNU-based process: +For development and debugging purposes, hwloc also offers the ability to work +on "fake" topologies: -shell$ ./configure --prefix=... -shell$ make -shell$ make install + * Symmetrical tree of resources generated from a list of level arities, see + Synthetic topologies. + * Remote machine simulation through the gathering of topology as XML files, + see Importing and exporting topologies from/to XML files. -hwloc- and netloc-specific configure options and requirements are documented in -sections hwloc Installation and Netloc Installation respectively. +hwloc can display the topology in a human-readable format, either in graphical +mode (X11), or by exporting in one of several different formats, including: +plain text, LaTeX tikzpicture, PDF, PNG, and FIG (see Command-line Examples +below). Note that some of the export formats require additional support +libraries. -Also note that if you install supplemental libraries in non-standard locations, -hwloc's configure script may not be able to find them without some help. You -may need to specify additional CPPFLAGS, LDFLAGS, or PKG_CONFIG_PATH values on -the configure command line. +hwloc offers a programming interface for manipulating topologies and objects. +It also brings a powerful CPU bitmap API that is used to describe topology +objects location on physical/logical processors. See the Programming Interface +below. It may also be used to binding applications onto certain cores or memory +nodes. Several utility programs are also provided to ease command-line +manipulation of topology objects, binding of processes, and so on. -For example, if libpciaccess was installed into /opt/pciaccess, hwloc's -configure script may not find it be default. Try adding PKG_CONFIG_PATH to the -./configure command line, like this: +Bindings for several other languages are available from the project website. -./configure PKG_CONFIG_PATH=/opt/pciaccess/lib/pkgconfig ... +Command-line Examples -Running the "lstopo" tool is a good way to check as a graphical output whether -hwloc properly detected the architecture of your node. Netloc command-line -tools can be used to display the network topology interconnecting your nodes. +On a 4-package 2-core machine with hyper-threading, the lstopo tool may show +the following graphical output: -Installing from a Git clone +[dudley] -Additionally, the code can be directly cloned from Git: +Here's the equivalent output in textual form: -shell$ git clone https://github.com/open-mpi/hwloc.git -shell$ cd hwloc -shell$ ./autogen.sh +Machine + NUMANode L#0 (P#0) + Package L#0 + L3 L#0 (4096KB) + L2 L#0 (1024KB) + L1 L#0 (16KB) + Core L#0 + PU L#0 (P#0) + PU L#1 (P#8) + L2 L#1 (1024KB) + L1 L#1 (16KB) + Core L#1 + PU L#2 (P#4) + PU L#3 (P#12) + Package L#1 + L3 L#1 (4096KB) + L2 L#2 (1024KB) + L1 L#2 (16KB) + Core L#2 + PU L#4 (P#1) + PU L#5 (P#9) + L2 L#3 (1024KB) + L1 L#3 (16KB) + Core L#3 + PU L#6 (P#5) + PU L#7 (P#13) + Package L#2 + L3 L#2 (4096KB) + L2 L#4 (1024KB) + L1 L#4 (16KB) + Core L#4 + PU L#8 (P#2) + PU L#9 (P#10) + L2 L#5 (1024KB) + L1 L#5 (16KB) + Core L#5 + PU L#10 (P#6) + PU L#11 (P#14) + Package L#3 + L3 L#3 (4096KB) + L2 L#6 (1024KB) + L1 L#6 (16KB) + Core L#6 + PU L#12 (P#3) + PU L#13 (P#11) + L2 L#7 (1024KB) + L1 L#7 (16KB) + Core L#7 + PU L#14 (P#7) + PU L#15 (P#15) -Note that GNU Autoconf >=2.63, Automake >=1.11 and Libtool >=2.2.6 are required -when building from a Git clone. +Note that there is also an equivalent output in XML that is meant for exporting +/importing topologies but it is hardly readable to human-beings (see Importing +and exporting topologies from/to XML files for details). -Nightly development snapshots are available on the web site, they can be -configured and built without any need for Git or GNU Autotools. +On a 4-package 2-core Opteron NUMA machine (with two core cores disallowed by +the administrator), the lstopo tool may show the following graphical output +(with --disallowed for displaying disallowed objects): + +[hagrid] + +Here's the equivalent output in textual form: + +Machine (32GB total) + Package L#0 + NUMANode L#0 (P#0 8190MB) + L2 L#0 (1024KB) + L1 L#0 (64KB) + Core L#0 + PU L#0 (P#0) + L2 L#1 (1024KB) + L1 L#1 (64KB) + Core L#1 + PU L#1 (P#1) + Package L#1 + NUMANode L#1 (P#1 8192MB) + L2 L#2 (1024KB) + L1 L#2 (64KB) + Core L#2 + PU L#2 (P#2) + L2 L#3 (1024KB) + L1 L#3 (64KB) + Core L#3 + PU L#3 (P#3) + Package L#2 + NUMANode L#2 (P#2 8192MB) + L2 L#4 (1024KB) + L1 L#4 (64KB) + Core L#4 + PU L#4 (P#4) + L2 L#5 (1024KB) + L1 L#5 (64KB) + Core L#5 + PU L#5 (P#5) + Package L#3 + NUMANode L#3 (P#3 8192MB) + L2 L#6 (1024KB) + L1 L#6 (64KB) + Core L#6 + PU L#6 (P#6) + L2 L#7 (1024KB) + L1 L#7 (64KB) + Core L#7 + PU L#7 (P#7) + +On a 2-package quad-core Xeon (pre-Nehalem, with 2 dual-core dies into each +package): + +[emmett] + +Here's the same output in textual form: + +Machine (total 16GB) + NUMANode L#0 (P#0 16GB) + Package L#0 + L2 L#0 (4096KB) + L1 L#0 (32KB) + Core L#0 + PU L#0 (P#0) + L1 L#1 (32KB) + Core L#1 + PU L#1 (P#4) + L2 L#1 (4096KB) + L1 L#2 (32KB) + Core L#2 + PU L#2 (P#2) + L1 L#3 (32KB) + Core L#3 + PU L#3 (P#6) + Package L#1 + L2 L#2 (4096KB) + L1 L#4 (32KB) + Core L#4 + PU L#4 (P#1) + L1 L#5 (32KB) + Core L#5 + PU L#5 (P#5) + L2 L#3 (4096KB) + L1 L#6 (32KB) + Core L#6 + PU L#6 (P#3) + L1 L#7 (32KB) + Core L#7 + PU L#7 (P#7) + +Programming Interface + +The basic interface is available in hwloc.h. Some higher-level functions are +available in hwloc/helper.h to reduce the need to manually manipulate objects +and follow links between them. Documentation for all these is provided later in +this document. Developers may also want to look at hwloc/inlines.h which +contains the actual inline code of some hwloc.h routines, and at this document, +which provides good higher-level topology traversal examples. + +To precisely define the vocabulary used by hwloc, a Terms and Definitions +section is available and should probably be read first. + +Each hwloc object contains a cpuset describing the list of processing units +that it contains. These bitmaps may be used for CPU binding and Memory binding. +hwloc offers an extensive bitmap manipulation interface in hwloc/bitmap.h. + +Moreover, hwloc also comes with additional helpers for interoperability with +several commonly used environments. See the Interoperability With Other +Software section for details. + +The complete API documentation is available in a full set of HTML pages, man +pages, and self-contained PDF files (formatted for both both US letter and A4 +formats) in the source tarball in doc/doxygen-doc/. + +NOTE: If you are building the documentation from a Git clone, you will need to +have Doxygen and pdflatex installed -- the documentation will be built during +the normal "make" process. The documentation is installed during "make install" +to $prefix/share/doc/hwloc/ and your systems default man page tree (under +$prefix, of course). + +Portability + +Operating System have varying support for CPU and memory binding, e.g. while +some Operating Systems provide interfaces for all kinds of CPU and memory +bindings, some others provide only interfaces for a limited number of kinds of +CPU and memory binding, and some do not provide any binding interface at all. +Hwloc's binding functions would then simply return the ENOSYS error (Function +not implemented), meaning that the underlying Operating System does not provide +any interface for them. CPU binding and Memory binding provide more information +on which hwloc binding functions should be preferred because interfaces for +them are usually available on the supported Operating Systems. + +Similarly, the ability of reporting topology information varies from one +platform to another. As shown in Command-line Examples, hwloc can obtain +information on a wide variety of hardware topologies. However, some platforms +and/or operating system versions will only report a subset of this information. +For example, on an PPC64-based system with 8 cores (each with 2 hardware +threads) running a default 2.6.18-based kernel from RHEL 5.4, hwloc is only +able to glean information about NUMA nodes and processor units (PUs). No +information about caches, packages, or cores is available. + +Here's the graphical output from lstopo on this platform when Simultaneous +Multi-Threading (SMT) is enabled: + +[ppc64-with] + +And here's the graphical output from lstopo on this platform when SMT is +disabled: + +[ppc64-with] + +Notice that hwloc only sees half the PUs when SMT is disabled. PU L#6, for +example, seems to change location from NUMA node #0 to #1. In reality, no PUs +"moved" -- they were simply re-numbered when hwloc only saw half as many (see +also Logical index in Indexes and Sets). Hence, PU L#6 in the SMT-disabled +picture probably corresponds to PU L#12 in the SMT-enabled picture. + +This same "PUs have disappeared" effect can be seen on other platforms -- even +platforms / OSs that provide much more information than the above PPC64 system. +This is an unfortunate side-effect of how operating systems report information +to hwloc. + +Note that upgrading the Linux kernel on the same PPC64 system mentioned above +to 2.6.34, hwloc is able to discover all the topology information. The +following picture shows the entire topology layout when SMT is enabled: + +[ppc64-full] + +Developers using the hwloc API or XML output for portable applications should +therefore be extremely careful to not make any assumptions about the structure +of data that is returned. For example, per the above reported PPC topology, it +is not safe to assume that PUs will always be descendants of cores. + +Additionally, future hardware may insert new topology elements that are not +available in this version of hwloc. Long-lived applications that are meant to +span multiple different hardware platforms should also be careful about making +structure assumptions. For example, a new element may someday exist between a +core and a PU. + +API Example + +The following small C example (available in the source tree as ``doc/examples/ +hwloc-hello.c'') prints the topology of the machine and performs some thread +and memory binding. More examples are available in the doc/examples/ directory +of the source tree. + +/* Example hwloc API program. +* +* See other examples under doc/examples/ in the source tree +* for more details. +* +* Copyright (c) 2009-2016 Inria. All rights reserved. +* Copyright (c) 2009-2011 Universit?eacute; Bordeaux +* Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved. +* See COPYING in top-level directory. +* +* hwloc-hello.c +*/ +#include "hwloc.h" +#include +#include +#include +static void print_children(hwloc_topology_t topology, hwloc_obj_t obj, +int depth) +{ +char type[32], attr[1024]; +unsigned i; +hwloc_obj_type_snprintf(type, sizeof(type), obj, 0); +printf("%*s%s", 2*depth, "", type); +if (obj->os_index != (unsigned) -1) +printf("#%u", obj->os_index); +hwloc_obj_attr_snprintf(attr, sizeof(attr), obj, " ", 0); +if (*attr) +printf("(%s)", attr); +printf("\n"); +for (i = 0; i < obj->arity; i++) { +print_children(topology, obj->children[i], depth + 1); +} +} +int main(void) +{ +int depth; +unsigned i, n; +unsigned long size; +int levels; +char string[128]; +int topodepth; +void *m; +hwloc_topology_t topology; +hwloc_cpuset_t cpuset; +hwloc_obj_t obj; +/* Allocate and initialize topology object. */ +hwloc_topology_init(&topology); +/* ... Optionally, put detection configuration here to ignore +some objects types, define a synthetic topology, etc.... +The default is to detect all the objects of the machine that +the caller is allowed to access. See Configure Topology +Detection. */ +/* Perform the topology detection. */ +hwloc_topology_load(topology); +/* Optionally, get some additional topology information +in case we need the topology depth later. */ +topodepth = hwloc_topology_get_depth(topology); +/***************************************************************** +* First example: +* Walk the topology with an array style, from level 0 (always +* the system level) to the lowest level (always the proc level). +*****************************************************************/ +for (depth = 0; depth < topodepth; depth++) { +printf("*** Objects at level %d\n", depth); +for (i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth); +i++) { +hwloc_obj_type_snprintf(string, sizeof(string), +hwloc_get_obj_by_depth(topology, depth, i), 0); +printf("Index %u: %s\n", i, string); +} +} +/***************************************************************** +* Second example: +* Walk the topology with a tree style. +*****************************************************************/ +printf("*** Printing overall tree\n"); +print_children(topology, hwloc_get_root_obj(topology), 0); +/***************************************************************** +* Third example: +* Print the number of packages. +*****************************************************************/ +depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PACKAGE); +if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) { +printf("*** The number of packages is unknown\n"); +} else { +printf("*** %u package(s)\n", +hwloc_get_nbobjs_by_depth(topology, depth)); +} +/***************************************************************** +* Fourth example: +* Compute the amount of cache that the first logical processor +* has above it. +*****************************************************************/ +levels = 0; +size = 0; +for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0); +obj; +obj = obj->parent) +if (hwloc_obj_type_is_cache(obj->type)) { +levels++; +size += obj->attr->cache.size; +} +printf("*** Logical processor 0 has %d caches totaling %luKB\n", +levels, size / 1024); +/***************************************************************** +* Fifth example: +* Bind to only one thread of the last core of the machine. +* +* First find out where cores are, or else smaller sets of CPUs if +* the OS doesn't have the notion of a "core". +*****************************************************************/ +depth = hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CORE); +/* Get last core. */ +obj = hwloc_get_obj_by_depth(topology, depth, +hwloc_get_nbobjs_by_depth(topology, depth) - 1); +if (obj) { +/* Get a copy of its cpuset that we may modify. */ +cpuset = hwloc_bitmap_dup(obj->cpuset); +/* Get only one logical processor (in case the core is +SMT/hyper-threaded). */ +hwloc_bitmap_singlify(cpuset); +/* And try to bind ourself there. */ +if (hwloc_set_cpubind(topology, cpuset, 0)) { +char *str; +int error = errno; +hwloc_bitmap_asprintf(&str, obj->cpuset); +printf("Couldn't bind to cpuset %s: %s\n", str, strerror(error)); +free(str); +} +/* Free our cpuset copy */ +hwloc_bitmap_free(cpuset); +} +/***************************************************************** +* Sixth example: +* Allocate some memory on the last NUMA node, bind some existing +* memory to the last NUMA node. +*****************************************************************/ +/* Get last node. There's always at least one. */ +n = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NUMANODE); +obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, n - 1); +size = 1024*1024; +m = hwloc_alloc_membind(topology, size, obj->nodeset, +HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); +hwloc_free(topology, m, size); +m = malloc(size); +hwloc_set_area_membind(topology, m, size, obj->nodeset, +HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); +free(m); +/* Destroy topology object. */ +hwloc_topology_destroy(topology); +return 0; +} + +hwloc provides a pkg-config executable to obtain relevant compiler and linker +flags. For example, it can be used thusly to compile applications that utilize +the hwloc library (assuming GNU Make): + +CFLAGS += $(shell pkg-config --cflags hwloc) +LDLIBS += $(shell pkg-config --libs hwloc) + +hwloc-hello: hwloc-hello.c + $(CC) hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS) + +On a machine 2 processor packages -- each package of which has two processing +cores -- the output from running hwloc-hello could be something like the +following: + +shell$ ./hwloc-hello +*** Objects at level 0 +Index 0: Machine +*** Objects at level 1 +Index 0: Package#0 +Index 1: Package#1 +*** Objects at level 2 +Index 0: Core#0 +Index 1: Core#1 +Index 2: Core#3 +Index 3: Core#2 +*** Objects at level 3 +Index 0: PU#0 +Index 1: PU#1 +Index 2: PU#2 +Index 3: PU#3 +*** Printing overall tree +Machine + Package#0 + Core#0 + PU#0 + Core#1 + PU#1 + Package#1 + Core#3 + PU#2 + Core#2 + PU#3 +*** 2 package(s) +*** Logical processor 0 has 0 caches totaling 0KB +shell$ Questions and Bugs @@ -80,6 +474,20 @@ www.open-mpi.org/community/lists/hwloc.php). There is also a #hwloc IRC channel on Libera Chat (irc.libera.chat). +History / Credits + +hwloc is the evolution and merger of the libtopology project and the Portable +Linux Processor Affinity (PLPA) (https://www.open-mpi.org/projects/plpa/) +project. Because of functional and ideological overlap, these two code bases +and ideas were merged and released under the name "hwloc" as an Open MPI +sub-project. + +libtopology was initially developed by the Inria Runtime Team-Project. PLPA was +initially developed by the Open MPI development team as a sub-project. Both are +now deprecated in favor of hwloc, which is distributed as an Open MPI +sub-project. -See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation. + +See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation, +actual links to related pages, images, etc. diff --git a/src/3rdparty/hwloc/VERSION b/src/3rdparty/hwloc/VERSION index af3c4889..cd608187 100644 --- a/src/3rdparty/hwloc/VERSION +++ b/src/3rdparty/hwloc/VERSION @@ -8,7 +8,7 @@ # Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too. major=2 -minor=9 +minor=10 release=0 # greek is used for alpha or beta release tags. If it is non-empty, @@ -22,7 +22,7 @@ greek= # The date when this release was created -date="Dec 14, 2022" +date="Dec 04, 2023" # If snapshot=1, then use the value from snapshot_version as the # entire hwloc version (i.e., ignore major, minor, release, and @@ -41,7 +41,6 @@ snapshot_version=${major}.${minor}.${release}${greek}-git # 2. Version numbers are described in the Libtool current:revision:age # format. -libhwloc_so_version=21:1:6 -libnetloc_so_version=0:0:0 +libhwloc_so_version=22:0:7 # Please also update the lines in contrib/windows/libhwloc.vcxproj diff --git a/src/3rdparty/hwloc/include/hwloc/autogen/config.h b/src/3rdparty/hwloc/include/hwloc/autogen/config.h index fcaf70ca..6f45f734 100644 --- a/src/3rdparty/hwloc/include/hwloc/autogen/config.h +++ b/src/3rdparty/hwloc/include/hwloc/autogen/config.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -11,9 +11,9 @@ #ifndef HWLOC_CONFIG_H #define HWLOC_CONFIG_H -#define HWLOC_VERSION "2.9.0" +#define HWLOC_VERSION "2.10.0" #define HWLOC_VERSION_MAJOR 2 -#define HWLOC_VERSION_MINOR 9 +#define HWLOC_VERSION_MINOR 10 #define HWLOC_VERSION_RELEASE 0 #define HWLOC_VERSION_GREEK "" diff --git a/src/3rdparty/hwloc/include/hwloc/bitmap.h b/src/3rdparty/hwloc/include/hwloc/bitmap.h index cd118b38..6b56bcb9 100644 --- a/src/3rdparty/hwloc/include/hwloc/bitmap.h +++ b/src/3rdparty/hwloc/include/hwloc/bitmap.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -50,9 +50,10 @@ extern "C" { * hwloc_bitmap_free(set); * \endcode * - * \note Most functions below return an int that may be negative in case of - * error. The usual error case would be an internal failure to realloc/extend + * \note Most functions below return 0 on success and -1 on error. + * The usual error case would be an internal failure to realloc/extend * the storage of the bitmap (\p errno would be set to \c ENOMEM). + * See also \ref hwlocality_api_error_reporting. * * \note Several examples of using the bitmap API are available under the * doc/examples/ directory in the source tree. @@ -83,7 +84,13 @@ typedef const struct hwloc_bitmap_s * hwloc_const_bitmap_t; */ HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc(void) __hwloc_attribute_malloc; -/** \brief Allocate a new full bitmap. */ +/** \brief Allocate a new full bitmap. + * + * \returns A valid bitmap or \c NULL. + * + * The bitmap should be freed by a corresponding call to + * hwloc_bitmap_free(). + */ HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc_full(void) __hwloc_attribute_malloc; /** \brief Free bitmap \p bitmap. @@ -119,11 +126,13 @@ HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buf /** \brief Stringify a bitmap into a newly allocated string. * - * \return -1 on error. + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); /** \brief Parse a bitmap string and stores it in bitmap \p bitmap. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string); @@ -144,11 +153,13 @@ HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_ /** \brief Stringify a bitmap into a newly allocated list string. * - * \return -1 on error. + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); /** \brief Parse a list string and stores it in bitmap \p bitmap. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string); @@ -168,11 +179,13 @@ HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, si /** \brief Stringify a bitmap into a newly allocated taskset-specific string. * - * \return -1 on error. + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); /** \brief Parse a taskset-specific bitmap string and stores it in bitmap \p bitmap. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_bitmap_taskset_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string); @@ -279,6 +292,7 @@ HWLOC_DECLSPEC int hwloc_bitmap_to_ulongs(hwloc_const_bitmap_t bitmap, unsigned * When called on the output of hwloc_topology_get_topology_cpuset(), * the returned number is large enough for all cpusets of the topology. * + * \return the number of unsigned longs required. * \return -1 if \p bitmap is infinite. */ HWLOC_DECLSPEC int hwloc_bitmap_nr_ulongs(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; @@ -305,21 +319,23 @@ HWLOC_DECLSPEC int hwloc_bitmap_isfull(hwloc_const_bitmap_t bitmap) __hwloc_attr /** \brief Compute the first index (least significant bit) in bitmap \p bitmap * - * \return -1 if no index is set in \p bitmap. + * \return the first index set in \p bitmap. + * \return -1 if \p bitmap is empty. */ HWLOC_DECLSPEC int hwloc_bitmap_first(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; /** \brief Compute the next index in bitmap \p bitmap which is after index \p prev * - * If \p prev is -1, the first index is returned. - * + * \return the first index set in \p bitmap if \p prev is \c -1. + * \return the next index set in \p bitmap if \p prev is not \c -1. * \return -1 if no index with higher index is set in \p bitmap. */ HWLOC_DECLSPEC int hwloc_bitmap_next(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure; /** \brief Compute the last index (most significant bit) in bitmap \p bitmap * - * \return -1 if no index is set in \p bitmap, or if \p bitmap is infinitely set. + * \return the last index set in \p bitmap. + * \return -1 if \p bitmap is empty, or if \p bitmap is infinitely set. */ HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; @@ -327,28 +343,29 @@ HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attrib * indexes that are in the bitmap). * * \return the number of indexes that are in the bitmap. - * * \return -1 if \p bitmap is infinitely set. */ HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; /** \brief Compute the first unset index (least significant bit) in bitmap \p bitmap * - * \return -1 if no index is unset in \p bitmap. + * \return the first unset index in \p bitmap. + * \return -1 if \p bitmap is full. */ HWLOC_DECLSPEC int hwloc_bitmap_first_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; /** \brief Compute the next unset index in bitmap \p bitmap which is after index \p prev * - * If \p prev is -1, the first unset index is returned. - * + * \return the first index unset in \p bitmap if \p prev is \c -1. + * \return the next index unset in \p bitmap if \p prev is not \c -1. * \return -1 if no index with higher index is unset in \p bitmap. */ HWLOC_DECLSPEC int hwloc_bitmap_next_unset(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure; /** \brief Compute the last unset index (most significant bit) in bitmap \p bitmap * - * \return -1 if no index is unset in \p bitmap, or if \p bitmap is infinitely set. + * \return the last index unset in \p bitmap. + * \return -1 if \p bitmap is full, or if \p bitmap is not infinitely set. */ HWLOC_DECLSPEC int hwloc_bitmap_last_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; @@ -428,6 +445,8 @@ HWLOC_DECLSPEC int hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bi /** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects. * * \return 1 if bitmaps intersect, 0 otherwise. + * + * \note The empty bitmap does not intersect any other bitmap. */ HWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure; diff --git a/src/3rdparty/hwloc/include/hwloc/cuda.h b/src/3rdparty/hwloc/include/hwloc/cuda.h index 72fb8ccb..e72f9728 100644 --- a/src/3rdparty/hwloc/include/hwloc/cuda.h +++ b/src/3rdparty/hwloc/include/hwloc/cuda.h @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2021 Inria. All rights reserved. + * Copyright © 2010-2023 Inria. All rights reserved. * Copyright © 2010-2011 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -42,6 +42,9 @@ extern "C" { /** \brief Return the domain, bus and device IDs of the CUDA device \p cudevice. * * Device \p cudevice must match the local machine. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, @@ -87,6 +90,9 @@ hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/cudart.h b/src/3rdparty/hwloc/include/hwloc/cudart.h index 676cffec..ad7f49f1 100644 --- a/src/3rdparty/hwloc/include/hwloc/cudart.h +++ b/src/3rdparty/hwloc/include/hwloc/cudart.h @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2021 Inria. All rights reserved. + * Copyright © 2010-2023 Inria. All rights reserved. * Copyright © 2010-2011 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -43,6 +43,9 @@ extern "C" { /** \brief Return the domain, bus and device IDs of the CUDA device whose index is \p idx. * * Device index \p idx must match the local machine. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, @@ -84,6 +87,9 @@ hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unus * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/diff.h b/src/3rdparty/hwloc/include/hwloc/diff.h index 0ad0486b..4d822434 100644 --- a/src/3rdparty/hwloc/include/hwloc/diff.h +++ b/src/3rdparty/hwloc/include/hwloc/diff.h @@ -1,5 +1,5 @@ /* - * Copyright © 2013-2020 Inria. All rights reserved. + * Copyright © 2013-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -222,6 +222,8 @@ enum hwloc_topology_diff_apply_flags_e { HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags); /** \brief Destroy a list of topology differences. + * + * \return 0. */ HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff); @@ -233,6 +235,8 @@ HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff); * This identifier is usually the name of the other XML file * that contains the reference topology. * + * \return 0 on success, -1 on error. + * * \note the pointer returned in refname should later be freed * by the caller. */ @@ -246,10 +250,17 @@ HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topol * This identifier is usually the name of the other XML file * that contains the reference topology. * This attribute is given back when reading the diff from XML. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath); /** \brief Load a list of topology differences from a XML buffer. + * + * Build a list of differences from the XML memory buffer given + * at \p xmlbuffer and of length \p buflen (including an ending \0). + * This buffer may have been filled earlier with + * hwloc_topology_diff_export_xmlbuffer(). * * If not \c NULL, \p refname will be filled with the identifier * string of the reference topology for the difference file, @@ -257,6 +268,8 @@ HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, co * This identifier is usually the name of the other XML file * that contains the reference topology. * + * \return 0 on success, -1 on error. + * * \note the pointer returned in refname should later be freed * by the caller. */ @@ -274,6 +287,8 @@ HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int * The returned buffer ends with a \0 that is included in the returned * length. * + * \return 0 on success, -1 on error. + * * \note The XML buffer should later be freed with hwloc_free_xmlbuffer(). */ HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen); diff --git a/src/3rdparty/hwloc/include/hwloc/distances.h b/src/3rdparty/hwloc/include/hwloc/distances.h index effa8663..71cca4b5 100644 --- a/src/3rdparty/hwloc/include/hwloc/distances.h +++ b/src/3rdparty/hwloc/include/hwloc/distances.h @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2022 Inria. All rights reserved. + * Copyright © 2010-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -131,6 +131,8 @@ enum hwloc_distances_kind_e { * * Each distance matrix returned in the \p distances array should be released * by the caller using hwloc_distances_release(). + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_get(hwloc_topology_t topology, @@ -140,6 +142,8 @@ hwloc_distances_get(hwloc_topology_t topology, /** \brief Retrieve distance matrices for object at a specific depth in the topology. * * Identical to hwloc_distances_get() with the additional \p depth filter. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth, @@ -149,6 +153,8 @@ hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth, /** \brief Retrieve distance matrices for object of a specific type. * * Identical to hwloc_distances_get() with the additional \p type filter. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, @@ -162,6 +168,8 @@ hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, * The name of the most common structure is "NUMALatency". * Others include "XGMIBandwidth", "XGMIHops", "XeLinkBandwidth", * and "NVLinkBandwidth". + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name, @@ -171,7 +179,12 @@ hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name, /** \brief Get a description of what a distances structure contains. * * For instance "NUMALatency" for hardware-provided NUMA distances (ACPI SLIT), - * or NULL if unknown. + * or \c NULL if unknown. + * + * \return the constant string with the name of the distance structure. + * + * \note The returned name should not be freed by the caller, + * it belongs to the hwloc library. */ HWLOC_DECLSPEC const char * hwloc_distances_get_name(hwloc_topology_t topology, struct hwloc_distances_s *distances); @@ -252,6 +265,8 @@ enum hwloc_distances_transform_e { * * \p flags must be \c 0 for now. * + * \return 0 on success, -1 on error for instance if flags are invalid. + * * \note Objects in distances array \p objs may be directly modified * in place without using hwloc_distances_transform(). * One may use hwloc_get_obj_with_same_locality() to easily convert @@ -272,6 +287,7 @@ HWLOC_DECLSPEC int hwloc_distances_transform(hwloc_topology_t topology, struct h /** \brief Find the index of an object in a distances structure. * + * \return the index of the object in the distances structure if any. * \return -1 if object \p obj is not involved in structure \p distances. */ static __hwloc_inline int @@ -289,6 +305,7 @@ hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj) * The distance from \p obj1 to \p obj2 is stored in the value pointed by * \p value1to2 and reciprocally. * + * \return 0 on success. * \return -1 if object \p obj1 or \p obj2 is not involved in structure \p distances. */ static __hwloc_inline int @@ -374,8 +391,8 @@ hwloc_distances_add_create(hwloc_topology_t topology, * * \p flags must be \c 0 for now. * - * \return \c 0 on success. - * \return \c -1 on error. + * \return 0 on success. + * \return -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_add_values(hwloc_topology_t topology, hwloc_distances_add_handle_t handle, @@ -411,8 +428,8 @@ enum hwloc_distances_add_flag_e { * * On error, the temporary distances structure and its content are destroyed. * - * \return \c 0 on success. - * \return \c -1 on error. + * \return 0 on success. + * \return -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_add_commit(hwloc_topology_t topology, hwloc_distances_add_handle_t handle, @@ -433,18 +450,24 @@ HWLOC_DECLSPEC int hwloc_distances_add_commit(hwloc_topology_t topology, * * If these distances were used to group objects, these additional * Group objects are not removed from the topology. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology); /** \brief Remove distance matrices for objects at a specific depth in the topology. * * Identical to hwloc_distances_remove() but only applies to one level of the topology. + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth); /** \brief Remove distance matrices for objects of a specific type in the topology. * * Identical to hwloc_distances_remove() but only applies to one level of the topology. + * + * \return 0 on success, -1 on error. */ static __hwloc_inline int hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type) @@ -458,6 +481,8 @@ hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type) /** \brief Release and remove the given distance matrice from the topology. * * This function includes a call to hwloc_distances_release(). + * + * \return 0 on success, -1 on error. */ HWLOC_DECLSPEC int hwloc_distances_release_remove(hwloc_topology_t topology, struct hwloc_distances_s *distances); diff --git a/src/3rdparty/hwloc/include/hwloc/export.h b/src/3rdparty/hwloc/include/hwloc/export.h index b178b77e..2ce5ab18 100644 --- a/src/3rdparty/hwloc/include/hwloc/export.h +++ b/src/3rdparty/hwloc/include/hwloc/export.h @@ -55,7 +55,7 @@ enum hwloc_topology_export_xml_flags_e { * * \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e. * - * \return -1 if a failure occured. + * \return 0 on success, or -1 on error. * * \note See also hwloc_topology_set_userdata_export_callback() * for exporting application-specific object userdata. @@ -91,7 +91,7 @@ HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const ch * * \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e. * - * \return -1 if a failure occured. + * \return 0 on success, or -1 on error. * * \note See also hwloc_topology_set_userdata_export_callback() * for exporting application-specific object userdata. @@ -145,13 +145,15 @@ HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t * that were given to the export callback. * * Only printable characters may be exported to XML string attributes. - * If a non-printable character is passed in \p name or \p buffer, - * the function returns -1 with errno set to EINVAL. * * If exporting binary data, the application should first encode into * printable characters only (or use hwloc_export_obj_userdata_base64()). * It should also take care of portability issues if the export may * be reimported on a different architecture. + * + * \return 0 on success. + * \return -1 with errno set to \c EINVAL if a non-printable character is + * passed in \p name or \b buffer. */ HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length); @@ -165,8 +167,14 @@ HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t to * This function may only be called from within the export() callback passed * to hwloc_topology_set_userdata_export_callback(). * + * The name must be made of printable characters for export to XML string attributes. + * * The function does not take care of portability issues if the export * may be reimported on a different architecture. + * + * \return 0 on success. + * \return -1 with errno set to \c EINVAL if a non-printable character is + * passed in \p name. */ HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length); diff --git a/src/3rdparty/hwloc/include/hwloc/gl.h b/src/3rdparty/hwloc/include/hwloc/gl.h index 56a402a8..2ad9284f 100644 --- a/src/3rdparty/hwloc/include/hwloc/gl.h +++ b/src/3rdparty/hwloc/include/hwloc/gl.h @@ -1,6 +1,6 @@ /* * Copyright © 2012 Blue Brain Project, EPFL. All rights reserved. - * Copyright © 2012-2021 Inria. All rights reserved. + * Copyright © 2012-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -102,7 +102,8 @@ hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology, * Retrieves the OpenGL display port (server) in \p port and device (screen) * in \p screen that correspond to the given hwloc OS device object. * - * \return \c -1 if none could be found. + * \return 0 on success. + * \return -1 if none could be found. * * The topology \p topology does not necessarily have to match the current * machine. For instance the topology may be an XML import of a remote host. diff --git a/src/3rdparty/hwloc/include/hwloc/glibc-sched.h b/src/3rdparty/hwloc/include/hwloc/glibc-sched.h index 3c5368be..d3f16f45 100644 --- a/src/3rdparty/hwloc/include/hwloc/glibc-sched.h +++ b/src/3rdparty/hwloc/include/hwloc/glibc-sched.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2020 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2011 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -52,6 +52,8 @@ extern "C" { * that takes a cpu_set_t as input parameter. * * \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC + * + * \return 0. */ static __hwloc_inline int hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset, @@ -80,6 +82,9 @@ hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute * that takes a cpu_set_t as input parameter. * * \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM if some internal reallocation failed. */ static __hwloc_inline int hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cpuset_t hwlocset, @@ -95,7 +100,8 @@ hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribu cpu = 0; while (count) { if (CPU_ISSET_S(cpu, schedsetsize, schedset)) { - hwloc_bitmap_set(hwlocset, cpu); + if (hwloc_bitmap_set(hwlocset, cpu) < 0) + return -1; count--; } cpu++; @@ -107,7 +113,8 @@ hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribu assert(schedsetsize == sizeof(cpu_set_t)); for(cpu=0; cpucpuset, set)) - return NULL; - while (!hwloc_bitmap_isincluded(obj->cpuset, set)) { - /* while the object intersects without being included, look at its children */ - hwloc_obj_t child = obj->first_child; - while (child) { - if (hwloc_bitmap_intersects(child->cpuset, set)) - break; - child = child->next_sibling; - } - if (!child) - /* no child intersects, return their father */ - return obj; - /* found one intersecting child, look at its children */ - obj = child; - } - /* obj is included, return it */ - return obj; -} - -/** \brief Get the set of largest objects covering exactly a given cpuset \p set - * - * \return the number of objects returned in \p objs. - */ -HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_t * __hwloc_restrict objs, int max); - -/** \brief Return the next object at depth \p depth included in CPU set \p set. - * - * If \p prev is \c NULL, return the first object at depth \p depth - * included in \p set. The next invokation should pass the previous - * return value in \p prev so as to obtain the next object in \p set. - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects at the given depth do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth, hwloc_obj_t prev) -{ - hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); - if (!next) - return NULL; - while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set))) - next = next->next_cousin; - return next; -} - -/** \brief Return the next object of type \p type included in CPU set \p set. - * - * If there are multiple or no depth for given type, return \c NULL - * and let the caller fallback to - * hwloc_get_next_obj_inside_cpuset_by_depth(). - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects of the given type do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type, hwloc_obj_t prev) -{ - int depth = hwloc_get_type_depth(topology, type); - if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) - return NULL; - return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev); -} - -/** \brief Return the (logically) \p idx -th object at depth \p depth included in CPU set \p set. - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects at the given depth do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth, unsigned idx) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth, unsigned idx) -{ - hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); - unsigned count = 0; - if (!obj) - return NULL; - while (obj) { - if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) { - if (count == idx) - return obj; - count++; - } - obj = obj->next_cousin; - } - return NULL; -} - -/** \brief Return the \p idx -th object of type \p type included in CPU set \p set. - * - * If there are multiple or no depth for given type, return \c NULL - * and let the caller fallback to - * hwloc_get_obj_inside_cpuset_by_depth(). - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects of the given type do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type, unsigned idx) -{ - int depth = hwloc_get_type_depth(topology, type); - if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) - return NULL; - return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx); -} - -/** \brief Return the number of objects at depth \p depth included in CPU set \p set. - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects at the given depth do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline unsigned -hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth) __hwloc_attribute_pure; -static __hwloc_inline unsigned -hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth) -{ - hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); - unsigned count = 0; - if (!obj) - return 0; - while (obj) { - if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) - count++; - obj = obj->next_cousin; - } - return count; -} - -/** \brief Return the number of objects of type \p type included in CPU set \p set. - * - * If no object for that type exists inside CPU set \p set, 0 is - * returned. If there are several levels with objects of that type - * inside CPU set \p set, -1 is returned. - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if objects of the given type do - * not have CPU sets (I/O objects). - */ -static __hwloc_inline int -hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type) __hwloc_attribute_pure; -static __hwloc_inline int -hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type) -{ - int depth = hwloc_get_type_depth(topology, type); - if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) - return 0; - if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) - return -1; /* FIXME: agregate nbobjs from different levels? */ - return (int) hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth); -} - -/** \brief Return the logical index among the objects included in CPU set \p set. - * - * Consult all objects in the same level as \p obj and inside CPU set \p set - * in the logical order, and return the index of \p obj within them. - * If \p set covers the entire topology, this is the logical index of \p obj. - * Otherwise, this is similar to a logical index within the part of the topology - * defined by CPU set \p set. - * - * \note Objects with empty CPU sets are ignored - * (otherwise they would be considered included in any given set). - * - * \note This function cannot work if obj does not have CPU sets (I/O objects). - */ -static __hwloc_inline int -hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, - hwloc_obj_t obj) __hwloc_attribute_pure; -static __hwloc_inline int -hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, - hwloc_obj_t obj) -{ - int idx = 0; - if (!hwloc_bitmap_isincluded(obj->cpuset, set)) - return -1; - /* count how many objects are inside the cpuset on the way from us to the beginning of the level */ - while ((obj = obj->prev_cousin) != NULL) - if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) - idx++; - return idx; -} - -/** @} */ - - - -/** \defgroup hwlocality_helper_find_covering Finding Objects covering at least CPU set - * @{ - */ - -/** \brief Get the child covering at least CPU set \p set. - * - * \return \c NULL if no child matches or if \p set is empty. - * - * \note This function cannot work if parent does not have a CPU set (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, - hwloc_obj_t parent) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, - hwloc_obj_t parent) -{ - hwloc_obj_t child; - if (hwloc_bitmap_iszero(set)) - return NULL; - child = parent->first_child; - while (child) { - if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset)) - return child; - child = child->next_sibling; - } - return NULL; -} - -/** \brief Get the lowest object covering at least CPU set \p set - * - * \return \c NULL if no object matches or if \p set is empty. - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) -{ - struct hwloc_obj *current = hwloc_get_root_obj(topology); - if (hwloc_bitmap_iszero(set) || !hwloc_bitmap_isincluded(set, current->cpuset)) - return NULL; - while (1) { - hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current); - if (!child) - return current; - current = child; - } -} - -/** \brief Iterate through same-depth objects covering at least CPU set \p set - * - * If object \p prev is \c NULL, return the first object at depth \p - * depth covering at least part of CPU set \p set. The next - * invokation should pass the previous return value in \p prev so as - * to obtain the next object covering at least another part of \p set. - * - * \note This function cannot work if objects at the given depth do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, - int depth, hwloc_obj_t prev) -{ - hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); - if (!next) - return NULL; - while (next && !hwloc_bitmap_intersects(set, next->cpuset)) - next = next->next_cousin; - return next; -} - -/** \brief Iterate through same-type objects covering at least CPU set \p set - * - * If object \p prev is \c NULL, return the first object of type \p - * type covering at least part of CPU set \p set. The next invokation - * should pass the previous return value in \p prev so as to obtain - * the next object of type \p type covering at least another part of - * \p set. - * - * If there are no or multiple depths for type \p type, \c NULL is returned. - * The caller may fallback to hwloc_get_next_obj_covering_cpuset_by_depth() - * for each depth. - * - * \note This function cannot work if objects of the given type do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, - hwloc_obj_type_t type, hwloc_obj_t prev) -{ - int depth = hwloc_get_type_depth(topology, type); - if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) - return NULL; - return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev); -} - -/** @} */ - - - -/** \defgroup hwlocality_helper_ancestors Looking at Ancestor and Child Objects - * @{ - * - * Be sure to see the figure in \ref termsanddefs that shows a - * complete topology tree, including depths, child/sibling/cousin - * relationships, and an example of an asymmetric topology where one - * package has fewer caches than its peers. - */ - -/** \brief Returns the ancestor object of \p obj at depth \p depth. - * - * \note \p depth should not be the depth of PU or NUMA objects - * since they are ancestors of no objects (except Misc or I/O). - * This function rather expects an intermediate level depth, - * such as the depth of Packages, Cores, or Caches. - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) -{ - hwloc_obj_t ancestor = obj; - if (obj->depth < depth) - return NULL; - while (ancestor && ancestor->depth > depth) - ancestor = ancestor->parent; - return ancestor; -} - -/** \brief Returns the ancestor object of \p obj with type \p type. - * - * \note \p type should not be ::HWLOC_OBJ_PU or ::HWLOC_OBJ_NUMANODE - * since these objects are ancestors of no objects (except Misc or I/O). - * This function rather expects an intermediate object type, - * such as ::HWLOC_OBJ_PACKAGE, ::HWLOC_OBJ_CORE, etc. - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) -{ - hwloc_obj_t ancestor = obj->parent; - while (ancestor && ancestor->type != type) - ancestor = ancestor->parent; - return ancestor; -} - -/** \brief Returns the common parent object to objects \p obj1 and \p obj2 */ -static __hwloc_inline hwloc_obj_t -hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure; -static __hwloc_inline hwloc_obj_t -hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) -{ - /* the loop isn't so easy since intermediate ancestors may have - * different depth, causing us to alternate between using obj1->parent - * and obj2->parent. Also, even if at some point we find ancestors of - * of the same depth, their ancestors may have different depth again. - */ - while (obj1 != obj2) { - while (obj1->depth > obj2->depth) - obj1 = obj1->parent; - while (obj2->depth > obj1->depth) - obj2 = obj2->parent; - if (obj1 != obj2 && obj1->depth == obj2->depth) { - obj1 = obj1->parent; - obj2 = obj2->parent; - } - } - return obj1; -} - -/** \brief Returns true if \p obj is inside the subtree beginning with ancestor object \p subtree_root. - * - * \note This function cannot work if \p obj and \p subtree_root objects do - * not have CPU sets (I/O or Misc objects). - */ -static __hwloc_inline int -hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure; -static __hwloc_inline int -hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) -{ - return obj->cpuset && subtree_root->cpuset && hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset); -} - -/** \brief Return the next child. - * - * Return the next child among the normal children list, - * then among the memory children list, then among the I/O - * children list, then among the Misc children list. - * - * If \p prev is \c NULL, return the first child. - * - * Return \c NULL when there is no next child. - */ -static __hwloc_inline hwloc_obj_t -hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev) -{ - hwloc_obj_t obj; - int state = 0; - if (prev) { - if (prev->type == HWLOC_OBJ_MISC) - state = 3; - else if (prev->type == HWLOC_OBJ_BRIDGE || prev->type == HWLOC_OBJ_PCI_DEVICE || prev->type == HWLOC_OBJ_OS_DEVICE) - state = 2; - else if (prev->type == HWLOC_OBJ_NUMANODE) - state = 1; - obj = prev->next_sibling; - } else { - obj = parent->first_child; - } - if (!obj && state == 0) { - obj = parent->memory_first_child; - state = 1; - } - if (!obj && state == 1) { - obj = parent->io_first_child; - state = 2; - } - if (!obj && state == 2) { - obj = parent->misc_first_child; - state = 3; - } - return obj; -} - -/** @} */ - - - /** \defgroup hwlocality_helper_types Kinds of object Type * @{ * @@ -496,6 +35,8 @@ hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_ * or I/O (i.e. hwloc_obj_type_is_io() returns 1) * or Misc (i.e. equal to ::HWLOC_OBJ_MISC). * It cannot be of more than one of these kinds. + * + * See also Object Kind in \ref termsanddefs. */ /** \brief Check whether an object type is Normal. @@ -565,6 +106,511 @@ hwloc_obj_type_is_icache(hwloc_obj_type_t type); +/** \defgroup hwlocality_helper_find_inside Finding Objects inside a CPU set + * @{ + */ + +/** \brief Get the first largest object included in the given cpuset \p set. + * + * \return the first object that is included in \p set and whose parent is not. + * \return \c NULL if no such object exists. + * + * This is convenient for iterating over all largest objects within a CPU set + * by doing a loop getting the first largest object and clearing its CPU set + * from the remaining CPU set. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set) +{ + hwloc_obj_t obj = hwloc_get_root_obj(topology); + if (!hwloc_bitmap_intersects(obj->cpuset, set)) + return NULL; + while (!hwloc_bitmap_isincluded(obj->cpuset, set)) { + /* while the object intersects without being included, look at its children */ + hwloc_obj_t child = obj->first_child; + while (child) { + if (hwloc_bitmap_intersects(child->cpuset, set)) + break; + child = child->next_sibling; + } + if (!child) + /* no child intersects, return their father */ + return obj; + /* found one intersecting child, look at its children */ + obj = child; + } + /* obj is included, return it */ + return obj; +} + +/** \brief Get the set of largest objects covering exactly a given cpuset \p set + * + * \return the number of objects returned in \p objs. + * \return -1 if no set of objects may cover that cpuset. + */ +HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_t * __hwloc_restrict objs, int max); + +/** \brief Return the next object at depth \p depth included in CPU set \p set. + * + * The next invokation should pass the previous return value in \p prev + * so as to obtain the next object in \p set. + * + * \return the first object at depth \p depth included in \p set if \p prev is \c NULL. + * \return the next object at depth \p depth included in \p set if \p prev is not \c NULL. + * \return \c NULL if there is no next object. + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects at the given depth do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth, hwloc_obj_t prev) +{ + hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); + if (!next) + return NULL; + while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set))) + next = next->next_cousin; + return next; +} + +/** \brief Return the next object of type \p type included in CPU set \p set. + * + * The next invokation should pass the previous return value in \p prev + * so as to obtain the next object in \p set. + * + * \return the first object of type \p type included in \p set if \p prev is \c NULL. + * \return the next object of type \p type included in \p set if \p prev is not \c NULL. + * \return \c NULL if there is no next object. + * \return \c NULL if there is no depth for the given type. + * \return \c NULL if there are multiple depths for the given type, + * the caller should fallback to hwloc_get_next_obj_inside_cpuset_by_depth(). + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects of the given type do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type, hwloc_obj_t prev) +{ + int depth = hwloc_get_type_depth(topology, type); + if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) + return NULL; + return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev); +} + +/** \brief Return the (logically) \p idx -th object at depth \p depth included in CPU set \p set. + * + * \return the object if any, \c NULL otherwise. + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects at the given depth do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth, unsigned idx) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth, unsigned idx) +{ + hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); + unsigned count = 0; + if (!obj) + return NULL; + while (obj) { + if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) { + if (count == idx) + return obj; + count++; + } + obj = obj->next_cousin; + } + return NULL; +} + +/** \brief Return the \p idx -th object of type \p type included in CPU set \p set. + * + * \return the object if any. + * \return \c NULL if there is no such object. + * \return \c NULL if there is no depth for given type. + * \return \c NULL if there are multiple depths for given type, + * the caller should fallback to hwloc_get_obj_inside_cpuset_by_depth(). + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects of the given type do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type, unsigned idx) +{ + int depth = hwloc_get_type_depth(topology, type); + if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) + return NULL; + return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx); +} + +/** \brief Return the number of objects at depth \p depth included in CPU set \p set. + * + * \return the number of objects. + * \return 0 if the depth is invalid. + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects at the given depth do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline unsigned +hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth) __hwloc_attribute_pure; +static __hwloc_inline unsigned +hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth) +{ + hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); + unsigned count = 0; + if (!obj) + return 0; + while (obj) { + if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) + count++; + obj = obj->next_cousin; + } + return count; +} + +/** \brief Return the number of objects of type \p type included in CPU set \p set. + * + * \return the number of objects. + * \return 0 if there are no objects of that type in the topology. + * \return -1 if there are multiple levels of objects of that type, + * the caller should fallback to hwloc_get_nbobjs_inside_cpuset_by_depth(). + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if objects of the given type do + * not have CPU sets (I/O objects). + */ +static __hwloc_inline int +hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type) __hwloc_attribute_pure; +static __hwloc_inline int +hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type) +{ + int depth = hwloc_get_type_depth(topology, type); + if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) + return 0; + if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) + return -1; /* FIXME: agregate nbobjs from different levels? */ + return (int) hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth); +} + +/** \brief Return the logical index among the objects included in CPU set \p set. + * + * Consult all objects in the same level as \p obj and inside CPU set \p set + * in the logical order, and return the index of \p obj within them. + * If \p set covers the entire topology, this is the logical index of \p obj. + * Otherwise, this is similar to a logical index within the part of the topology + * defined by CPU set \p set. + * + * \return the logical index among the objects included in the set if any. + * \return -1 if the object is not included in the set. + * + * \note Objects with empty CPU sets are ignored + * (otherwise they would be considered included in any given set). + * + * \note This function cannot work if obj does not have CPU sets (I/O objects). + */ +static __hwloc_inline int +hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, + hwloc_obj_t obj) __hwloc_attribute_pure; +static __hwloc_inline int +hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, + hwloc_obj_t obj) +{ + int idx = 0; + if (!hwloc_bitmap_isincluded(obj->cpuset, set)) + return -1; + /* count how many objects are inside the cpuset on the way from us to the beginning of the level */ + while ((obj = obj->prev_cousin) != NULL) + if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) + idx++; + return idx; +} + +/** @} */ + + + +/** \defgroup hwlocality_helper_find_covering Finding Objects covering at least CPU set + * @{ + */ + +/** \brief Get the child covering at least CPU set \p set. + * + * \return the child that covers the set entirely. + * \return \c NULL if no child matches or if \p set is empty. + * + * \note This function cannot work if parent does not have a CPU set (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, + hwloc_obj_t parent) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, + hwloc_obj_t parent) +{ + hwloc_obj_t child; + if (hwloc_bitmap_iszero(set)) + return NULL; + child = parent->first_child; + while (child) { + if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset)) + return child; + child = child->next_sibling; + } + return NULL; +} + +/** \brief Get the lowest object covering at least CPU set \p set + * + * \return the lowest object covering the set entirely. + * \return \c NULL if no object matches or if \p set is empty. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) +{ + struct hwloc_obj *current = hwloc_get_root_obj(topology); + if (hwloc_bitmap_iszero(set) || !hwloc_bitmap_isincluded(set, current->cpuset)) + return NULL; + while (1) { + hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current); + if (!child) + return current; + current = child; + } +} + +/** \brief Iterate through same-depth objects covering at least CPU set \p set + * + * The next invokation should pass the previous return value in \p prev so as + * to obtain the next object covering at least another part of \p set. + * + * \return the first object at depth \p depth covering at least part of CPU set \p set + * if object \p prev is \c NULL. + * \return the next one if \p prev is not \c NULL. + * \return \c NULL if there is no next object. + * + * \note This function cannot work if objects at the given depth do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, + int depth, hwloc_obj_t prev) +{ + hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); + if (!next) + return NULL; + while (next && !hwloc_bitmap_intersects(set, next->cpuset)) + next = next->next_cousin; + return next; +} + +/** \brief Iterate through same-type objects covering at least CPU set \p set + * + * The next invokation should pass the previous return value in \p prev so as to obtain + * the next object of type \p type covering at least another part of \p set. + * + * \return the first object of type \p type covering at least part of CPU set \p set + * if object \p prev is \c NULL. + * \return the next one if \p prev is not \c NULL. + * \return \c NULL if there is no next object. + * \return \c NULL if there is no depth for the given type. + * \return \c NULL if there are multiple depths for the given type, + * the caller should fallback to hwloc_get_next_obj_covering_cpuset_by_depth(). + * + * \note This function cannot work if objects of the given type do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, + hwloc_obj_type_t type, hwloc_obj_t prev) +{ + int depth = hwloc_get_type_depth(topology, type); + if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) + return NULL; + return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev); +} + +/** @} */ + + + +/** \defgroup hwlocality_helper_ancestors Looking at Ancestor and Child Objects + * @{ + * + * Be sure to see the figure in \ref termsanddefs that shows a + * complete topology tree, including depths, child/sibling/cousin + * relationships, and an example of an asymmetric topology where one + * package has fewer caches than its peers. + */ + +/** \brief Returns the ancestor object of \p obj at depth \p depth. + * + * \return the ancestor if any. + * \return \c NULL if no such ancestor exists. + * + * \note \p depth should not be the depth of PU or NUMA objects + * since they are ancestors of no objects (except Misc or I/O). + * This function rather expects an intermediate level depth, + * such as the depth of Packages, Cores, or Caches. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) +{ + hwloc_obj_t ancestor = obj; + if (obj->depth < depth) + return NULL; + while (ancestor && ancestor->depth > depth) + ancestor = ancestor->parent; + return ancestor; +} + +/** \brief Returns the ancestor object of \p obj with type \p type. + * + * \return the ancestor if any. + * \return \c NULL if no such ancestor exists. + * + * \note if multiple matching ancestors exist (e.g. multiple levels of ::HWLOC_OBJ_GROUP) + * the lowest one is returned. + * + * \note \p type should not be ::HWLOC_OBJ_PU or ::HWLOC_OBJ_NUMANODE + * since these objects are ancestors of no objects (except Misc or I/O). + * This function rather expects an intermediate object type, + * such as ::HWLOC_OBJ_PACKAGE, ::HWLOC_OBJ_CORE, etc. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) +{ + hwloc_obj_t ancestor = obj->parent; + while (ancestor && ancestor->type != type) + ancestor = ancestor->parent; + return ancestor; +} + +/** \brief Returns the common parent object to objects \p obj1 and \p obj2. + * + * \return the common ancestor. + * + * \note This function cannot return \c NULL. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure; +static __hwloc_inline hwloc_obj_t +hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) +{ + /* the loop isn't so easy since intermediate ancestors may have + * different depth, causing us to alternate between using obj1->parent + * and obj2->parent. Also, even if at some point we find ancestors of + * of the same depth, their ancestors may have different depth again. + */ + while (obj1 != obj2) { + while (obj1->depth > obj2->depth) + obj1 = obj1->parent; + while (obj2->depth > obj1->depth) + obj2 = obj2->parent; + if (obj1 != obj2 && obj1->depth == obj2->depth) { + obj1 = obj1->parent; + obj2 = obj2->parent; + } + } + return obj1; +} + +/** \brief Returns true if \p obj is inside the subtree beginning with ancestor object \p subtree_root. + * + * \return 1 is the object is in the subtree, 0 otherwise. + * + * \note This function cannot work if \p obj and \p subtree_root objects do + * not have CPU sets (I/O or Misc objects). + */ +static __hwloc_inline int +hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure; +static __hwloc_inline int +hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) +{ + return obj->cpuset && subtree_root->cpuset && hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset); +} + +/** \brief Return the next child. + * + * Return the next child among the normal children list, + * then among the memory children list, then among the I/O + * children list, then among the Misc children list. + * + * \return the first child if \p prev is \c NULL. + * \return the next child if \p prev is not \c NULL. + * \return \c NULL when there is no next child. + */ +static __hwloc_inline hwloc_obj_t +hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev) +{ + hwloc_obj_t obj; + int state = 0; + if (prev) { + if (prev->type == HWLOC_OBJ_MISC) + state = 3; + else if (hwloc_obj_type_is_io(prev->type)) + state = 2; + else if (hwloc_obj_type_is_memory(prev->type)) + state = 1; + obj = prev->next_sibling; + } else { + obj = parent->first_child; + } + if (!obj && state == 0) { + obj = parent->memory_first_child; + state = 1; + } + if (!obj && state == 1) { + obj = parent->io_first_child; + state = 2; + } + if (!obj && state == 2) { + obj = parent->misc_first_child; + state = 3; + } + return obj; +} + +/** @} */ + + + /** \defgroup hwlocality_helper_find_cache Looking at Cache Objects * @{ */ @@ -578,17 +624,19 @@ hwloc_obj_type_is_icache(hwloc_obj_type_t type); * corresponding type such as ::HWLOC_OBJ_L1ICACHE, except that it may * also return a Unified cache when looking for an instruction cache. * - * If no cache level matches, ::HWLOC_TYPE_DEPTH_UNKNOWN is returned. + * \return the depth of the unique matching unified cache level is returned + * if \p cachetype is ::HWLOC_OBJ_CACHE_UNIFIED. * - * If \p cachetype is ::HWLOC_OBJ_CACHE_UNIFIED, the depth of the - * unique matching unified cache level is returned. + * \return the depth of either a matching cache level or a unified cache level + * if \p cachetype is ::HWLOC_OBJ_CACHE_DATA or ::HWLOC_OBJ_CACHE_INSTRUCTION. * - * If \p cachetype is ::HWLOC_OBJ_CACHE_DATA or ::HWLOC_OBJ_CACHE_INSTRUCTION, - * either a matching cache, or a unified cache is returned. + * \return the depth of the matching level + * if \p cachetype is \c -1 but only one level matches. * - * If \p cachetype is \c -1, it is ignored and multiple levels may - * match. The function returns either the depth of a uniquely matching - * level or ::HWLOC_TYPE_DEPTH_MULTIPLE. + * \return ::HWLOC_TYPE_DEPTH_MULTIPLE + * if \p cachetype is \c -1 but multiple levels match. + * + * \return ::HWLOC_TYPE_DEPTH_UNKNOWN if no cache level matches. */ static __hwloc_inline int hwloc_get_cache_type_depth (hwloc_topology_t topology, @@ -622,7 +670,7 @@ hwloc_get_cache_type_depth (hwloc_topology_t topology, /** \brief Get the first data (or unified) cache covering a cpuset \p set * - * \return \c NULL if no cache matches. + * \return a covering cache, or \c NULL if no cache matches. */ static __hwloc_inline hwloc_obj_t hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure; @@ -640,7 +688,8 @@ hwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t /** \brief Get the first data (or unified) cache shared between an object and somebody else. * - * \return \c NULL if no cache matches or if an invalid object is given. + * \return a shared cache. + * \return \c NULL if no cache matches or if an invalid object is given (e.g. I/O object). */ static __hwloc_inline hwloc_obj_t hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure; @@ -684,6 +733,8 @@ hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute * If \p which is larger than the number of PUs in a core there were originally set in \p cpuset, * no PU is kept for that core. * + * \return 0. + * * \note PUs that are not below a Core object are ignored * (for instance if the topology does not contain any Core object). * None of them is removed from \p cpuset. @@ -698,6 +749,8 @@ HWLOC_DECLSPEC int hwloc_bitmap_singlify_per_core(hwloc_topology_t topology, hwl * one may iterate over the bits of the resulting CPU set with * hwloc_bitmap_foreach_begin(), and find the corresponding PUs * with this function. + * + * \return the PU object, or \c NULL if none matches. */ static __hwloc_inline hwloc_obj_t hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure; @@ -719,6 +772,8 @@ hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) * one may iterate over the bits of the resulting nodeset with * hwloc_bitmap_foreach_begin(), and find the corresponding NUMA nodes * with this function. + * + * \return the NUMA node object, or \c NULL if none matches. */ static __hwloc_inline hwloc_obj_t hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure; @@ -756,6 +811,8 @@ HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc * For instance, if type1 is PACKAGE, idx1 is 2, type2 is CORE and idx2 * is 3, return the fourth core object below the third package. * + * \return a matching object if any, \c NULL otherwise. + * * \note This function requires these objects to have a CPU set. */ static __hwloc_inline hwloc_obj_t @@ -789,6 +846,8 @@ hwloc_get_obj_below_by_type (hwloc_topology_t topology, * and idxv contains 0, 1 and 2, return the third core object below * the second package below the first NUMA node. * + * \return a matching object if any, \c NULL otherwise. + * * \note This function requires all these objects and the root object * to have a CPU set. */ @@ -885,6 +944,8 @@ enum hwloc_distrib_flags_e { * * \p flags should be 0 or a OR'ed set of ::hwloc_distrib_flags_e. * + * \return 0 on success, -1 on error. + * * \note This function requires the \p roots objects to have a CPU set. */ static __hwloc_inline int @@ -961,6 +1022,8 @@ hwloc_distrib(hwloc_topology_t topology, * * \return the complete CPU set of processors of the system. * + * \note This function cannot return \c NULL. + * * \note The returned cpuset is not newly allocated and should thus not be * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * @@ -975,6 +1038,8 @@ hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_ * provides topology information. This is equivalent to the cpuset of the * system object. * + * \note This function cannot return \c NULL. + * * \note The returned cpuset is not newly allocated and should thus not be * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * @@ -987,6 +1052,8 @@ hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_ * * \return the CPU set of allowed processors of the system. * + * \note This function cannot return \c NULL. + * * \note If the topology flag ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED was not set, * this is identical to hwloc_topology_get_topology_cpuset(), which means * all PUs are allowed. @@ -1006,6 +1073,8 @@ hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_p * * \return the complete node set of memory of the system. * + * \note This function cannot return \c NULL. + * * \note The returned nodeset is not newly allocated and should thus not be * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * @@ -1020,6 +1089,8 @@ hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute * provides topology information. This is equivalent to the nodeset of the * system object. * + * \note This function cannot return \c NULL. + * * \note The returned nodeset is not newly allocated and should thus not be * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * @@ -1032,6 +1103,8 @@ hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute * * \return the node set of allowed memory of the system. * + * \note This function cannot return \c NULL. + * * \note If the topology flag ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED was not set, * this is identical to hwloc_topology_get_topology_nodeset(), which means * all NUMA nodes are allowed. @@ -1066,6 +1139,9 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_ * * Hence the entire topology CPU set is converted into the set of all nodes * that have some local CPUs. + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM on internal reallocation failure. */ static __hwloc_inline int hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) @@ -1090,6 +1166,9 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, * * Hence the entire topology node set is converted into the set of all CPUs * that have some local NUMA nodes. + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM on internal reallocation failure. */ static __hwloc_inline int hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) @@ -1122,6 +1201,10 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl * because it has non-NULL CPU and node sets * and because its locality is the same as \p ioobj. * + * \return a non-I/O object. + * + * \note This function cannot return \c NULL. + * * \note The resulting object is usually a normal object but it could also * be a memory object (e.g. NUMA node) in future platforms if I/O objects * ever get attached to memory instead of CPUs. @@ -1140,6 +1223,8 @@ hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused /** \brief Get the next PCI device in the system. * * \return the first PCI device if \p prev is \c NULL. + * \return the next PCI device if \p prev is not \c NULL. + * \return \c NULL if there is no next PCI device. */ static __hwloc_inline hwloc_obj_t hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev) @@ -1149,6 +1234,8 @@ hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev) /** \brief Find the PCI device object matching the PCI bus id * given domain, bus device and function PCI bus id. + * + * \return a matching PCI device object if any, \c NULL otherwise. */ static __hwloc_inline hwloc_obj_t hwloc_get_pcidev_by_busid(hwloc_topology_t topology, @@ -1167,6 +1254,8 @@ hwloc_get_pcidev_by_busid(hwloc_topology_t topology, /** \brief Find the PCI device object matching the PCI bus id * given as a string xxxx:yy:zz.t or yy:zz.t. + * + * \return a matching PCI device object if any, \c NULL otherwise. */ static __hwloc_inline hwloc_obj_t hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid) @@ -1186,6 +1275,8 @@ hwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid) /** \brief Get the next OS device in the system. * * \return the first OS device if \p prev is \c NULL. + * \return the next OS device if \p prev is not \c NULL. + * \return \c NULL if there is no next OS device. */ static __hwloc_inline hwloc_obj_t hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev) @@ -1196,6 +1287,8 @@ hwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev) /** \brief Get the next bridge in the system. * * \return the first bridge if \p prev is \c NULL. + * \return the next bridge if \p prev is not \c NULL. + * \return \c NULL if there is no next bridge. */ static __hwloc_inline hwloc_obj_t hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev) @@ -1204,6 +1297,8 @@ hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev) } /* \brief Checks whether a given bridge covers a given PCI bus. + * + * \return 1 if it covers, 0 if not. */ static __hwloc_inline int hwloc_bridge_covers_pcibus(hwloc_obj_t bridge, diff --git a/src/3rdparty/hwloc/include/hwloc/levelzero.h b/src/3rdparty/hwloc/include/hwloc/levelzero.h index 4c356fc8..dcdcf1fb 100644 --- a/src/3rdparty/hwloc/include/hwloc/levelzero.h +++ b/src/3rdparty/hwloc/include/hwloc/levelzero.h @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Inria. All rights reserved. + * Copyright © 2021-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -44,8 +44,9 @@ extern "C" { * the Level Zero device \p device. * * Topology \p topology and device \p device must match the local machine. - * The Level Zero must have been initialized with Sysman enabled - * (ZES_ENABLE_SYSMAN=1 in the environment). + * The Level Zero library must have been initialized with Sysman enabled + * (by calling zesInit(0) if supported, + * or by setting ZES_ENABLE_SYSMAN=1 in the environment). * I/O devices detection and the Level Zero component are not needed in the * topology. * @@ -55,6 +56,9 @@ extern "C" { * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/linux-libnuma.h b/src/3rdparty/hwloc/include/hwloc/linux-libnuma.h index 0e2cc19f..adb05c09 100644 --- a/src/3rdparty/hwloc/include/hwloc/linux-libnuma.h +++ b/src/3rdparty/hwloc/include/hwloc/linux-libnuma.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2017 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2010, 2012 Université Bordeaux * See COPYING in top-level directory. */ @@ -50,6 +50,8 @@ extern "C" { * This function may be used before calling set_mempolicy, mbind, migrate_pages * or any other function that takes an array of unsigned long and a maximal * node number as input parameter. + * + * \return 0. */ static __hwloc_inline int hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, @@ -84,6 +86,8 @@ hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpus * This function may be used before calling set_mempolicy, mbind, migrate_pages * or any other function that takes an array of unsigned long and a maximal * node number as input parameter. + * + * \return 0. */ static __hwloc_inline int hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, @@ -119,6 +123,9 @@ hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nod * This function may be used after calling get_mempolicy or any other function * that takes an array of unsigned long as output parameter (and possibly * a maximal node number as input parameter). + * + * \return 0 on success. + * \return -1 on error, for instance if failing an internal reallocation. */ static __hwloc_inline int hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset, @@ -130,7 +137,8 @@ hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) if (node->os_index < maxnode && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8))))) - hwloc_bitmap_or(cpuset, cpuset, node->cpuset); + if (hwloc_bitmap_or(cpuset, cpuset, node->cpuset) < 0) + return -1; return 0; } @@ -142,6 +150,9 @@ hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t * This function may be used after calling get_mempolicy or any other function * that takes an array of unsigned long as output parameter (and possibly * a maximal node number as input parameter). + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM if some internal reallocation failed. */ static __hwloc_inline int hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset, @@ -153,7 +164,8 @@ hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) if (node->os_index < maxnode && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8))))) - hwloc_bitmap_set(nodeset, node->os_index); + if (hwloc_bitmap_set(nodeset, node->os_index) < 0) + return -1; return 0; } @@ -184,7 +196,7 @@ hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset * This function may be used before calling many numa_ functions * that use a struct bitmask as an input parameter. * - * \return newly allocated struct bitmask. + * \return newly allocated struct bitmask, or \c NULL on error. */ static __hwloc_inline struct bitmask * hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc; @@ -209,7 +221,7 @@ hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpu * This function may be used before calling many numa_ functions * that use a struct bitmask as an input parameter. * - * \return newly allocated struct bitmask. + * \return newly allocated struct bitmask, or \c NULL on error. */ static __hwloc_inline struct bitmask * hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc; @@ -231,6 +243,9 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no * * This function may be used after calling many numa_ functions * that use a struct bitmask as an output parameter. + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM if some internal reallocation failed. */ static __hwloc_inline int hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset, @@ -241,7 +256,8 @@ hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_ hwloc_bitmap_zero(cpuset); while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) if (numa_bitmask_isbitset(bitmask, node->os_index)) - hwloc_bitmap_or(cpuset, cpuset, node->cpuset); + if (hwloc_bitmap_or(cpuset, cpuset, node->cpuset) < 0) + return -1; return 0; } @@ -249,6 +265,9 @@ hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_ * * This function may be used after calling many numa_ functions * that use a struct bitmask as an output parameter. + * + * \return 0 on success. + * \return -1 with errno set to \c ENOMEM if some internal reallocation failed. */ static __hwloc_inline int hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset, @@ -259,7 +278,8 @@ hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodese hwloc_bitmap_zero(nodeset); while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) if (numa_bitmask_isbitset(bitmask, node->os_index)) - hwloc_bitmap_set(nodeset, node->os_index); + if (hwloc_bitmap_set(nodeset, node->os_index) < 0) + return -1; return 0; } diff --git a/src/3rdparty/hwloc/include/hwloc/linux.h b/src/3rdparty/hwloc/include/hwloc/linux.h index d76633b0..3f69be74 100644 --- a/src/3rdparty/hwloc/include/hwloc/linux.h +++ b/src/3rdparty/hwloc/include/hwloc/linux.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2021 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2011 Université Bordeaux * See COPYING in top-level directory. */ @@ -38,6 +38,8 @@ extern "C" { * The behavior is exactly the same as the Linux sched_setaffinity system call, * but uses a hwloc cpuset. * + * \return 0 on success, -1 on error. + * * \note This is equivalent to calling hwloc_set_proc_cpubind() with * HWLOC_CPUBIND_THREAD as flags. */ @@ -52,6 +54,8 @@ HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t * The behavior is exactly the same as the Linux sched_getaffinity system call, * but uses a hwloc cpuset. * + * \return 0 on success, -1 on error. + * * \note This is equivalent to calling hwloc_get_proc_cpubind() with * ::HWLOC_CPUBIND_THREAD as flags. */ @@ -62,6 +66,8 @@ HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t * The CPU-set \p set (previously allocated by the caller) * is filled with the PU which the thread last ran on. * + * \return 0 on success, -1 on error. + * * \note This is equivalent to calling hwloc_get_proc_last_cpu_location() with * ::HWLOC_CPUBIND_THREAD as flags. */ @@ -72,6 +78,8 @@ HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topolo * Might be used when reading CPU set from sysfs attributes such as topology * and caches for processors, or local_cpus for devices. * + * \return 0 on success, -1 on error. + * * \note This function ignores the HWLOC_FSROOT environment variable. */ HWLOC_DECLSPEC int hwloc_linux_read_path_as_cpumask(const char *path, hwloc_bitmap_t set); diff --git a/src/3rdparty/hwloc/include/hwloc/memattrs.h b/src/3rdparty/hwloc/include/hwloc/memattrs.h index acf4da53..10332b8e 100644 --- a/src/3rdparty/hwloc/include/hwloc/memattrs.h +++ b/src/3rdparty/hwloc/include/hwloc/memattrs.h @@ -1,5 +1,5 @@ /* - * Copyright © 2019-2022 Inria. All rights reserved. + * Copyright © 2019-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -54,6 +54,10 @@ extern "C" { * Attribute values for these nodes, if any, may then be obtained with * hwloc_memattr_get_value() and manually compared with the desired criteria. * + * Memory attributes are also used internally to build Memory Tiers which provide + * an easy way to distinguish NUMA nodes of different kinds, as explained + * in \ref heteromem. + * * \sa An example is available in doc/examples/memory-attributes.c in the source tree. * * \note The API also supports specific objects as initiator, @@ -178,6 +182,9 @@ enum hwloc_memattr_id_e { typedef unsigned hwloc_memattr_id_t; /** \brief Return the identifier of the memory attribute with the given name. + * + * \return 0 on success. + * \return -1 with errno set to \c EINVAL if no such attribute exists. */ HWLOC_DECLSPEC int hwloc_memattr_get_by_name(hwloc_topology_t topology, @@ -247,6 +254,8 @@ enum hwloc_local_numanode_flag_e { * or the number of nodes that would have been stored if there were * enough room. * + * \return 0 on success or -1 on error. + * * \note Some of these NUMA nodes may not have any memory attribute * values and hence not be reported as actual targets in other functions. * @@ -276,6 +285,10 @@ hwloc_get_local_numanode_objs(hwloc_topology_t topology, * * \p flags must be \c 0 for now. * + * \return 0 on success. + * \return -1 on error, for instance with errno set to \c EINVAL if flags + * are invalid or no such attribute exists. + * * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET * when refering to accesses performed by CPU cores. * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc, @@ -307,7 +320,10 @@ hwloc_memattr_get_value(hwloc_topology_t topology, * * \p flags must be \c 0 for now. * - * If there are no matching targets, \c -1 is returned with \p errno set to \c ENOENT; + * \return 0 on success. + * \return -1 with errno set to \c ENOENT if there are no matching targets. + * \return -1 with errno set to \c EINVAL if flags are invalid, + * or no such attribute exists. * * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET * when refering to accesses performed by CPU cores. @@ -323,10 +339,6 @@ hwloc_memattr_get_best_target(hwloc_topology_t topology, hwloc_obj_t *best_target, hwloc_uint64_t *value); /** \brief Return the best initiator for the given attribute and target NUMA node. - * - * If the attribute does not relate to a specific initiator - * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR), - * \c -1 is returned and \p errno is set to \c EINVAL. * * If \p value is non \c NULL, the corresponding value is returned there. * @@ -342,7 +354,10 @@ hwloc_memattr_get_best_target(hwloc_topology_t topology, * * \p flags must be \c 0 for now. * - * If there are no matching initiators, \c -1 is returned with \p errno set to \c ENOENT; + * \return 0 on success. + * \return -1 with errno set to \c ENOENT if there are no matching initiators. + * \return -1 with errno set to \c EINVAL if the attribute does not relate to a specific initiator + * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR). */ HWLOC_DECLSPEC int hwloc_memattr_get_best_initiator(hwloc_topology_t topology, @@ -359,6 +374,9 @@ hwloc_memattr_get_best_initiator(hwloc_topology_t topology, */ /** \brief Return the name of a memory attribute. + * + * \return 0 on success. + * \return -1 with errno set to \c EINVAL if the attribute does not exist. */ HWLOC_DECLSPEC int hwloc_memattr_get_name(hwloc_topology_t topology, @@ -368,6 +386,9 @@ hwloc_memattr_get_name(hwloc_topology_t topology, /** \brief Return the flags of the given attribute. * * Flags are a OR'ed set of ::hwloc_memattr_flag_e. + * + * \return 0 on success. + * \return -1 with errno set to \c EINVAL if the attribute does not exist. */ HWLOC_DECLSPEC int hwloc_memattr_get_flags(hwloc_topology_t topology, @@ -397,6 +418,9 @@ enum hwloc_memattr_flag_e { * Add a specific memory attribute that is not defined in ::hwloc_memattr_id_e. * Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain at least * one of ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST. + * + * \return 0 on success. + * \return -1 with errno set to \c EBUSY if another attribute already uses this name. */ HWLOC_DECLSPEC int hwloc_memattr_register(hwloc_topology_t topology, @@ -421,6 +445,8 @@ hwloc_memattr_register(hwloc_topology_t topology, * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc, * but users may for instance use it to provide custom information about * host memory accesses performed by GPUs. + * + * \return 0 on success or -1 on error. */ HWLOC_DECLSPEC int hwloc_memattr_set_value(hwloc_topology_t topology, @@ -460,6 +486,8 @@ hwloc_memattr_set_value(hwloc_topology_t topology, * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute * values. * + * \return 0 on success or -1 on error. + * * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET * when referring to accesses performed by CPU cores. * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc, @@ -497,6 +525,8 @@ hwloc_memattr_get_targets(hwloc_topology_t topology, * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR), * no initiator is returned. * + * \return 0 on success or -1 on error. + * * \note This function is meant for tools and debugging (listing internal information) * rather than for application queries. Applications should rather select useful * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute diff --git a/src/3rdparty/hwloc/include/hwloc/nvml.h b/src/3rdparty/hwloc/include/hwloc/nvml.h index 57f36a85..558a97d0 100644 --- a/src/3rdparty/hwloc/include/hwloc/nvml.h +++ b/src/3rdparty/hwloc/include/hwloc/nvml.h @@ -1,5 +1,5 @@ /* - * Copyright © 2012-2021 Inria. All rights reserved. + * Copyright © 2012-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -51,6 +51,9 @@ extern "C" { * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/opencl.h b/src/3rdparty/hwloc/include/hwloc/opencl.h index 395b32e3..9810504e 100644 --- a/src/3rdparty/hwloc/include/hwloc/opencl.h +++ b/src/3rdparty/hwloc/include/hwloc/opencl.h @@ -1,5 +1,5 @@ /* - * Copyright © 2012-2021 Inria. All rights reserved. + * Copyright © 2012-2023 Inria. All rights reserved. * Copyright © 2013, 2018 Université Bordeaux. All right reserved. * See COPYING in top-level directory. */ @@ -69,6 +69,9 @@ typedef union { /** \brief Return the domain, bus and device IDs of the OpenCL device \p device. * * Device \p device must match the local machine. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_opencl_get_device_pci_busid(cl_device_id device, @@ -126,6 +129,9 @@ hwloc_opencl_get_device_pci_busid(cl_device_id device, * This function is currently only implemented in a meaningful way for * Linux with the AMD or NVIDIA OpenCL implementation; other systems will simply * get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if the device could not be found. */ static __hwloc_inline int hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h b/src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h index 7cee137e..875b12a9 100644 --- a/src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h +++ b/src/3rdparty/hwloc/include/hwloc/openfabrics-verbs.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2021 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2010 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -57,6 +57,9 @@ extern "C" { * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/plugins.h b/src/3rdparty/hwloc/include/hwloc/plugins.h index d7abb02c..f3db648c 100644 --- a/src/3rdparty/hwloc/include/hwloc/plugins.h +++ b/src/3rdparty/hwloc/include/hwloc/plugins.h @@ -164,7 +164,7 @@ struct hwloc_disc_status { */ unsigned excluded_phases; - /** \brief OR'ed set of hwloc_disc_status_flag_e */ + /** \brief OR'ed set of ::hwloc_disc_status_flag_e */ unsigned long flags; }; diff --git a/src/3rdparty/hwloc/include/hwloc/rename.h b/src/3rdparty/hwloc/include/hwloc/rename.h index 279ecd84..d5687b69 100644 --- a/src/3rdparty/hwloc/include/hwloc/rename.h +++ b/src/3rdparty/hwloc/include/hwloc/rename.h @@ -176,6 +176,7 @@ extern "C" { #define hwloc_topology_insert_misc_object HWLOC_NAME(topology_insert_misc_object) #define hwloc_topology_alloc_group_object HWLOC_NAME(topology_alloc_group_object) +#define hwloc_topology_free_group_object HWLOC_NAME(topology_free_group_object) #define hwloc_topology_insert_group_object HWLOC_NAME(topology_insert_group_object) #define hwloc_obj_add_other_obj_sets HWLOC_NAME(obj_add_other_obj_sets) #define hwloc_topology_refresh HWLOC_NAME(topology_refresh) diff --git a/src/3rdparty/hwloc/include/hwloc/rsmi.h b/src/3rdparty/hwloc/include/hwloc/rsmi.h index 55aa1272..34db3267 100644 --- a/src/3rdparty/hwloc/include/hwloc/rsmi.h +++ b/src/3rdparty/hwloc/include/hwloc/rsmi.h @@ -1,5 +1,5 @@ /* - * Copyright © 2012-2021 Inria. All rights reserved. + * Copyright © 2012-2023 Inria. All rights reserved. * Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved. * Written by Advanced Micro Devices, * See COPYING in top-level directory. @@ -55,6 +55,9 @@ extern "C" { * * This function is currently only implemented in a meaningful way for * Linux; other systems will simply get a full cpuset. + * + * \return 0 on success. + * \return -1 on error, for instance if device information could not be found. */ static __hwloc_inline int hwloc_rsmi_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, diff --git a/src/3rdparty/hwloc/include/hwloc/shmem.h b/src/3rdparty/hwloc/include/hwloc/shmem.h index 86f57b4f..c91e0d8e 100644 --- a/src/3rdparty/hwloc/include/hwloc/shmem.h +++ b/src/3rdparty/hwloc/include/hwloc/shmem.h @@ -1,5 +1,5 @@ /* - * Copyright © 2013-2018 Inria. All rights reserved. + * Copyright © 2013-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -48,6 +48,8 @@ extern "C" { * This length (in bytes) must be used in hwloc_shmem_topology_write() * and hwloc_shmem_topology_adopt() later. * + * \return the length, or -1 on error, for instance if flags are invalid. + * * \note Flags \p flags are currently unused, must be 0. */ HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology, @@ -74,9 +76,10 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology, * is not. However the caller may also allocate it manually in shared memory * to share it as well. * - * \return -1 with errno set to EBUSY if the virtual memory mapping defined + * \return 0 on success. + * \return -1 with errno set to \c EBUSY if the virtual memory mapping defined * by \p mmap_address and \p length isn't available in the process. - * \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address + * \return -1 with errno set to \c EINVAL if \p fileoffset, \p mmap_address * or \p length aren't page-aligned. */ HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology, @@ -112,14 +115,16 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology, * * \note This function takes care of calling hwloc_topology_abi_check(). * - * \return -1 with errno set to EBUSY if the virtual memory mapping defined + * \return 0 on success. + * + * \return -1 with errno set to \c EBUSY if the virtual memory mapping defined * by \p mmap_address and \p length isn't available in the process. * - * \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address + * \return -1 with errno set to \c EINVAL if \p fileoffset, \p mmap_address * or \p length aren't page-aligned, or do not match what was given to * hwloc_shmem_topology_write() earlier. * - * \return -1 with errno set to EINVAL if the layout of the topology structure + * \return -1 with errno set to \c EINVAL if the layout of the topology structure * is different between the writer process and the adopter process. */ HWLOC_DECLSPEC int hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp, diff --git a/src/3rdparty/hwloc/include/private/netloc.h b/src/3rdparty/hwloc/include/private/netloc.h deleted file mode 100644 index c070c54c..00000000 --- a/src/3rdparty/hwloc/include/private/netloc.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright © 2014 Cisco Systems, Inc. All rights reserved. - * Copyright © 2013-2014 University of Wisconsin-La Crosse. - * All rights reserved. - * Copyright © 2015-2017 Inria. All rights reserved. - * - * $COPYRIGHT$ - * - * Additional copyrights may follow - * See COPYING in top-level directory. - * - * $HEADER$ - */ - -#ifndef _NETLOC_PRIVATE_H_ -#define _NETLOC_PRIVATE_H_ - -#include -#include -#include -#include -#include - -#define NETLOCFILE_VERSION 1 - -#ifdef NETLOC_SCOTCH -#include -#include -#define NETLOC_int SCOTCH_Num -#else -#define NETLOC_int int -#endif - -/* - * "Import" a few things from hwloc - */ -#define __netloc_attribute_unused __hwloc_attribute_unused -#define __netloc_attribute_malloc __hwloc_attribute_malloc -#define __netloc_attribute_const __hwloc_attribute_const -#define __netloc_attribute_pure __hwloc_attribute_pure -#define __netloc_attribute_deprecated __hwloc_attribute_deprecated -#define __netloc_attribute_may_alias __hwloc_attribute_may_alias -#define NETLOC_DECLSPEC HWLOC_DECLSPEC - - -/********************************************************************** - * Types - **********************************************************************/ - -/** - * Definitions for Comparators - * \sa These are the return values from the following functions: - * netloc_network_compare, netloc_dt_edge_t_compare, netloc_dt_node_t_compare - */ -typedef enum { - NETLOC_CMP_SAME = 0, /**< Compared as the Same */ - NETLOC_CMP_SIMILAR = -1, /**< Compared as Similar, but not the Same */ - NETLOC_CMP_DIFF = -2 /**< Compared as Different */ -} netloc_compare_type_t; - -/** - * Enumerated type for the various types of supported networks - */ -typedef enum { - NETLOC_NETWORK_TYPE_ETHERNET = 1, /**< Ethernet network */ - NETLOC_NETWORK_TYPE_INFINIBAND = 2, /**< InfiniBand network */ - NETLOC_NETWORK_TYPE_INVALID = 3 /**< Invalid network */ -} netloc_network_type_t; - -/** - * Enumerated type for the various types of supported topologies - */ -typedef enum { - NETLOC_TOPOLOGY_TYPE_INVALID = -1, /**< Invalid */ - NETLOC_TOPOLOGY_TYPE_TREE = 1, /**< Tree */ -} netloc_topology_type_t; - -/** - * Enumerated type for the various types of nodes - */ -typedef enum { - NETLOC_NODE_TYPE_HOST = 0, /**< Host (a.k.a., network addressable endpoint - e.g., MAC Address) node */ - NETLOC_NODE_TYPE_SWITCH = 1, /**< Switch node */ - NETLOC_NODE_TYPE_INVALID = 2 /**< Invalid node */ -} netloc_node_type_t; - -typedef enum { - NETLOC_ARCH_TREE = 0, /* Fat tree */ -} netloc_arch_type_t; - - -/* Pre declarations to avoid inter dependency problems */ -/** \cond IGNORE */ -struct netloc_topology_t; -typedef struct netloc_topology_t netloc_topology_t; -struct netloc_node_t; -typedef struct netloc_node_t netloc_node_t; -struct netloc_edge_t; -typedef struct netloc_edge_t netloc_edge_t; -struct netloc_physical_link_t; -typedef struct netloc_physical_link_t netloc_physical_link_t; -struct netloc_path_t; -typedef struct netloc_path_t netloc_path_t; - -struct netloc_arch_tree_t; -typedef struct netloc_arch_tree_t netloc_arch_tree_t; -struct netloc_arch_node_t; -typedef struct netloc_arch_node_t netloc_arch_node_t; -struct netloc_arch_node_slot_t; -typedef struct netloc_arch_node_slot_t netloc_arch_node_slot_t; -struct netloc_arch_t; -typedef struct netloc_arch_t netloc_arch_t; -/** \endcond */ - -/** - * \struct netloc_topology_t - * \brief Netloc Topology Context - * - * An opaque data structure used to reference a network topology. - * - * \note Must be initialized with \ref netloc_topology_construct() - */ -struct netloc_topology_t { - /** Topology path */ - char *topopath; - /** Subnet ID */ - char *subnet_id; - - /** Node List */ - netloc_node_t *nodes; /* Hash table of nodes by physical_id */ - netloc_node_t *nodesByHostname; /* Hash table of nodes by hostname */ - - netloc_physical_link_t *physical_links; /* Hash table with physcial links */ - - /** Partition List */ - UT_array *partitions; - - /** Hwloc topology List */ - char *hwlocpath; - UT_array *topos; - hwloc_topology_t *hwloc_topos; - - /** Type of the graph */ - netloc_topology_type_t type; -}; - -/** - * \brief Netloc Node Type - * - * Represents the concept of a node (a.k.a., vertex, endpoint) within a network - * graph. This could be a server or a network switch. The \ref node_type parameter - * will distinguish the exact type of node this represents in the graph. - */ -struct netloc_node_t { - UT_hash_handle hh; /* makes this structure hashable with physical_id */ - UT_hash_handle hh2; /* makes this structure hashable with hostname */ - - /** Physical ID of the node */ - char physical_id[20]; - - /** Logical ID of the node (if any) */ - int logical_id; - - /** Type of the node */ - netloc_node_type_t type; - - /* Pointer to physical_links */ - UT_array *physical_links; - - /** Description information from discovery (if any) */ - char *description; - - /** - * Application-given private data pointer. - * Initialized to NULL, and not used by the netloc library. - */ - void * userdata; - - /** Outgoing edges from this node */ - netloc_edge_t *edges; - - UT_array *subnodes; /* the group of nodes for the virtual nodes */ - - netloc_path_t *paths; - - char *hostname; - - UT_array *partitions; /* index in the list from the topology */ - - hwloc_topology_t hwlocTopo; - int hwlocTopoIdx; -}; - -/** - * \brief Netloc Edge Type - * - * Represents the concept of a directed edge within a network graph. - * - * \note We do not point to the netloc_node_t structure directly to - * simplify the representation, and allow the information to more easily - * be entered into the data store without circular references. - * \todo JJH Is the note above still true? - */ -struct netloc_edge_t { - UT_hash_handle hh; /* makes this structure hashable */ - - netloc_node_t *dest; - - int id; - - /** Pointers to the parent node */ - netloc_node_t *node; - - /* Pointer to physical_links */ - UT_array *physical_links; - - /** total gbits of the links */ - float total_gbits; - - UT_array *partitions; /* index in the list from the topology */ - - UT_array *subnode_edges; /* for edges going to virtual nodes */ - - struct netloc_edge_t *other_way; - - /** - * Application-given private data pointer. - * Initialized to NULL, and not used by the netloc library. - */ - void * userdata; -}; - - -struct netloc_physical_link_t { - UT_hash_handle hh; /* makes this structure hashable */ - - int id; // TODO long long - netloc_node_t *src; - netloc_node_t *dest; - int ports[2]; - char *width; - char *speed; - - netloc_edge_t *edge; - - int other_way_id; - struct netloc_physical_link_t *other_way; - - UT_array *partitions; /* index in the list from the topology */ - - /** gbits of the link from speed and width */ - float gbits; - - /** Description information from discovery (if any) */ - char *description; -}; - -struct netloc_path_t { - UT_hash_handle hh; /* makes this structure hashable */ - char dest_id[20]; - UT_array *links; -}; - - -/********************************************************************** - * Architecture structures - **********************************************************************/ -struct netloc_arch_tree_t { - NETLOC_int num_levels; - NETLOC_int *degrees; - NETLOC_int *cost; -}; - -struct netloc_arch_node_t { - UT_hash_handle hh; /* makes this structure hashable */ - char *name; /* Hash key */ - netloc_node_t *node; /* Corresponding node */ - int idx_in_topo; /* idx with ghost hosts to have complete topo */ - int num_slots; /* it is not the real number of slots but the maximum slot idx */ - int *slot_idx; /* corresponding idx in slot_tree */ - int *slot_os_idx; /* corresponding os index for each leaf in tree */ - netloc_arch_tree_t *slot_tree; /* Tree built from hwloc */ - int num_current_slots; /* Number of PUs */ - NETLOC_int *current_slots; /* indices in the complete tree */ - int *slot_ranks; /* corresponding MPI rank for each leaf in tree */ -}; - -struct netloc_arch_node_slot_t { - netloc_arch_node_t *node; - int slot; -}; - -struct netloc_arch_t { - netloc_topology_t *topology; - int has_slots; /* if slots are included in the architecture */ - netloc_arch_type_t type; - union { - netloc_arch_tree_t *node_tree; - netloc_arch_tree_t *global_tree; - } arch; - netloc_arch_node_t *nodes_by_name; - netloc_arch_node_slot_t *node_slot_by_idx; /* node_slot by index in complete topo */ - NETLOC_int num_current_hosts; /* if has_slots, host is a slot, else host is a node */ - NETLOC_int *current_hosts; /* indices in the complete topology */ -}; - -/********************************************************************** - * Topology Functions - **********************************************************************/ -/** - * Allocate a topology handle. - * - * User is responsible for calling \ref netloc_detach on the topology handle. - * The network parameter information is deep copied into the topology handle, so the - * user may destruct the network handle after calling this function and/or reuse - * the network handle. - * - * \returns NETLOC_SUCCESS on success - * \returns NETLOC_ERROR upon an error. - */ -netloc_topology_t *netloc_topology_construct(char *path); - -/** - * Destruct a topology handle - * - * \param topology A valid pointer to a \ref netloc_topology_t handle created - * from a prior call to \ref netloc_topology_construct. - * - * \returns NETLOC_SUCCESS on success - * \returns NETLOC_ERROR upon an error. - */ -int netloc_topology_destruct(netloc_topology_t *topology); - -int netloc_topology_find_partition_idx(netloc_topology_t *topology, char *partition_name); - -int netloc_topology_read_hwloc(netloc_topology_t *topology, int num_nodes, - netloc_node_t **node_list); - -#define netloc_topology_iter_partitions(topology,partition) \ - for ((partition) = (char **)utarray_front(topology->partitions); \ - (partition) != NULL; \ - (partition) = (char **)utarray_next(topology->partitions, partition)) - -#define netloc_topology_iter_hwloctopos(topology,hwloctopo) \ - for ((hwloctopo) = (char **)utarray_front(topology->topos); \ - (hwloctopo) != NULL; \ - (hwloctopo) = (char **)utarray_next(topology->topos, hwloctopo)) - -#define netloc_topology_find_node(topology,node_id,node) \ - HASH_FIND_STR(topology->nodes, node_id, node) - -#define netloc_topology_iter_nodes(topology,node,_tmp) \ - HASH_ITER(hh, topology->nodes, node, _tmp) - -#define netloc_topology_num_nodes(topology) \ - HASH_COUNT(topology->nodes) - -/*************************************************/ - - -/** - * Constructor for netloc_node_t - * - * User is responsible for calling the destructor on the handle. - * - * Returns - * A newly allocated pointer to the network information. - */ -netloc_node_t *netloc_node_construct(void); - -/** - * Destructor for netloc_node_t - * - * \param node A valid node handle - * - * Returns - * NETLOC_SUCCESS on success - * NETLOC_ERROR on error - */ -int netloc_node_destruct(netloc_node_t *node); - -char *netloc_node_pretty_print(netloc_node_t* node); - -#define netloc_node_get_num_subnodes(node) \ - utarray_len((node)->subnodes) - -#define netloc_node_get_subnode(node,i) \ - (*(netloc_node_t **)utarray_eltptr((node)->subnodes, (i))) - -#define netloc_node_get_num_edges(node) \ - utarray_len((node)->edges) - -#define netloc_node_get_edge(node,i) \ - (*(netloc_edge_t **)utarray_eltptr((node)->edges, (i))) - -#define netloc_node_iter_edges(node,edge,_tmp) \ - HASH_ITER(hh, node->edges, edge, _tmp) - -#define netloc_node_iter_paths(node,path,_tmp) \ - HASH_ITER(hh, node->paths, path, _tmp) - -#define netloc_node_is_host(node) \ - (node->type == NETLOC_NODE_TYPE_HOST) - -#define netloc_node_is_switch(node) \ - (node->type == NETLOC_NODE_TYPE_SWITCH) - -#define netloc_node_iter_paths(node, path,_tmp) \ - HASH_ITER(hh, node->paths, path, _tmp) - -int netloc_node_is_in_partition(netloc_node_t *node, int partition); - -/*************************************************/ - - -/** - * Constructor for netloc_edge_t - * - * User is responsible for calling the destructor on the handle. - * - * Returns - * A newly allocated pointer to the edge information. - */ -netloc_edge_t *netloc_edge_construct(void); - -/** - * Destructor for netloc_edge_t - * - * \param edge A valid edge handle - * - * Returns - * NETLOC_SUCCESS on success - * NETLOC_ERROR on error - */ -int netloc_edge_destruct(netloc_edge_t *edge); - -char * netloc_edge_pretty_print(netloc_edge_t* edge); - -void netloc_edge_reset_uid(void); - -int netloc_edge_is_in_partition(netloc_edge_t *edge, int partition); - -#define netloc_edge_get_num_links(edge) \ - utarray_len((edge)->physical_links) - -#define netloc_edge_get_link(edge,i) \ - (*(netloc_physical_link_t **)utarray_eltptr((edge)->physical_links, (i))) - -#define netloc_edge_get_num_subedges(edge) \ - utarray_len((edge)->subnode_edges) - -#define netloc_edge_get_subedge(edge,i) \ - (*(netloc_edge_t **)utarray_eltptr((edge)->subnode_edges, (i))) - -/*************************************************/ - - -/** - * Constructor for netloc_physical_link_t - * - * User is responsible for calling the destructor on the handle. - * - * Returns - * A newly allocated pointer to the physical link information. - */ -netloc_physical_link_t * netloc_physical_link_construct(void); - -/** - * Destructor for netloc_physical_link_t - * - * Returns - * NETLOC_SUCCESS on success - * NETLOC_ERROR on error - */ -int netloc_physical_link_destruct(netloc_physical_link_t *link); - -char * netloc_link_pretty_print(netloc_physical_link_t* link); - -/*************************************************/ - - -netloc_path_t *netloc_path_construct(void); -int netloc_path_destruct(netloc_path_t *path); - - -/********************************************************************** - * Architecture functions - **********************************************************************/ - -netloc_arch_t * netloc_arch_construct(void); - -int netloc_arch_destruct(netloc_arch_t *arch); - -int netloc_arch_build(netloc_arch_t *arch, int add_slots); - -int netloc_arch_set_current_resources(netloc_arch_t *arch); - -int netloc_arch_set_global_resources(netloc_arch_t *arch); - -int netloc_arch_node_get_hwloc_info(netloc_arch_node_t *arch); - -void netloc_arch_tree_complete(netloc_arch_tree_t *tree, UT_array **down_degrees_by_level, - int num_hosts, int **parch_idx); - -NETLOC_int netloc_arch_tree_num_leaves(netloc_arch_tree_t *tree); - - -/********************************************************************** - * Access functions of various elements of the topology - **********************************************************************/ - -#define netloc_get_num_partitions(object) \ - utarray_len((object)->partitions) - -#define netloc_get_partition(object,i) \ - (*(int *)utarray_eltptr((object)->partitions, (i))) - - -#define netloc_path_iter_links(path,link) \ - for ((link) = (netloc_physical_link_t **)utarray_front(path->links); \ - (link) != NULL; \ - (link) = (netloc_physical_link_t **)utarray_next(path->links, link)) - -/********************************************************************** - * Misc functions - **********************************************************************/ - -/** - * Decode the network type - * - * \param net_type A valid member of the \ref netloc_network_type_t type - * - * \returns NULL if the type is invalid - * \returns A string for that \ref netloc_network_type_t type - */ -static inline const char * netloc_network_type_decode(netloc_network_type_t net_type) { - if( NETLOC_NETWORK_TYPE_ETHERNET == net_type ) { - return "ETH"; - } - else if( NETLOC_NETWORK_TYPE_INFINIBAND == net_type ) { - return "IB"; - } - else { - return NULL; - } -} - -/** - * Decode the node type - * - * \param node_type A valid member of the \ref netloc_node_type_t type - * - * \returns NULL if the type is invalid - * \returns A string for that \ref netloc_node_type_t type - */ -static inline const char * netloc_node_type_decode(netloc_node_type_t node_type) { - if( NETLOC_NODE_TYPE_SWITCH == node_type ) { - return "SW"; - } - else if( NETLOC_NODE_TYPE_HOST == node_type ) { - return "CA"; - } - else { - return NULL; - } -} - -ssize_t netloc_line_get(char **lineptr, size_t *n, FILE *stream); - -char *netloc_line_get_next_token(char **string, char c); - -int netloc_build_comm_mat(char *filename, int *pn, double ***pmat); - -#define STRDUP_IF_NOT_NULL(str) (NULL == str ? NULL : strdup(str)) -#define STR_EMPTY_IF_NULL(str) (NULL == str ? "" : str) - - -#endif // _NETLOC_PRIVATE_H_ diff --git a/src/3rdparty/hwloc/include/private/private.h b/src/3rdparty/hwloc/include/private/private.h index c61acb71..3e3f71d9 100644 --- a/src/3rdparty/hwloc/include/private/private.h +++ b/src/3rdparty/hwloc/include/private/private.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * @@ -245,6 +245,12 @@ struct hwloc_topology { * temporary variables during discovery */ + /* set to 1 at the beginning of load() if the filter of any cpu cache type (L1 to L3i) is not NONE, + * may be checked by backends before querying caches + * (when they don't know the level of caches they are querying). + */ + int want_some_cpu_caches; + /* machine-wide memory. * temporarily stored there by OSes that only provide this without NUMA information, * and actually used later by the core. @@ -420,7 +426,7 @@ extern void hwloc_internal_memattrs_need_refresh(hwloc_topology_t topology); extern void hwloc_internal_memattrs_refresh(hwloc_topology_t topology); extern int hwloc_internal_memattrs_dup(hwloc_topology_t new, hwloc_topology_t old); extern int hwloc_internal_memattr_set_value(hwloc_topology_t topology, hwloc_memattr_id_t id, hwloc_obj_type_t target_type, hwloc_uint64_t target_gp_index, unsigned target_os_index, struct hwloc_internal_location_s *initiator, hwloc_uint64_t value); -extern int hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology); +extern int hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology, int force_subtype); extern void hwloc_internal_cpukinds_init(hwloc_topology_t topology); extern int hwloc_internal_cpukinds_rank(hwloc_topology_t topology); @@ -477,6 +483,7 @@ extern char * hwloc_progname(struct hwloc_topology *topology); #define HWLOC_GROUP_KIND_INTEL_DIE 104 /* no subkind */ #define HWLOC_GROUP_KIND_S390_BOOK 110 /* subkind 0 is book, subkind 1 is drawer (group of books) */ #define HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT 120 /* no subkind */ +#define HWLOC_GROUP_KIND_AMD_COMPLEX 121 /* no subkind */ /* then, OS-specific groups */ #define HWLOC_GROUP_KIND_SOLARIS_PG_HW_PERF 200 /* subkind is group width */ #define HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN 210 /* subkind is SDL level */ diff --git a/src/3rdparty/hwloc/include/private/xml.h b/src/3rdparty/hwloc/include/private/xml.h index 3af5ba1e..49e80565 100644 --- a/src/3rdparty/hwloc/include/private/xml.h +++ b/src/3rdparty/hwloc/include/private/xml.h @@ -19,13 +19,14 @@ HWLOC_DECLSPEC int hwloc__xml_verbose(void); typedef struct hwloc__xml_import_state_s { struct hwloc__xml_import_state_s *parent; - /* globals shared because the entire stack of states during import */ + /* globals shared between the entire stack of states during import */ struct hwloc_xml_backend_data_s *global; /* opaque data used to store backend-specific data. * statically allocated to allow stack-allocation by the common code without knowing actual backend needs. + * libxml is 3 ptrs. nolibxml is 3 ptr + one int. */ - char data[32]; + char data[4 * SIZEOF_VOID_P]; } * hwloc__xml_import_state_t; struct hwloc__xml_imported_v1distances_s { @@ -74,8 +75,9 @@ typedef struct hwloc__xml_export_state_s { /* opaque data used to store backend-specific data. * statically allocated to allow stack-allocation by the common code without knowing actual backend needs. + * libxml is 1 ptr. nolibxml is 1 ptr + 2 size_t + 3 ints. */ - char data[40]; + char data[6 * SIZEOF_VOID_P]; } * hwloc__xml_export_state_t; HWLOC_DECLSPEC void hwloc__xml_export_topology(hwloc__xml_export_state_t parentstate, hwloc_topology_t topology, unsigned long flags); diff --git a/src/3rdparty/hwloc/src/components.c b/src/3rdparty/hwloc/src/components.c index b0381c83..003995a6 100644 --- a/src/3rdparty/hwloc/src/components.c +++ b/src/3rdparty/hwloc/src/components.c @@ -94,8 +94,7 @@ static hwloc_dlhandle hwloc_dlopenext(const char *_filename) { hwloc_dlhandle handle; char *filename = NULL; - (void) asprintf(&filename, "%s.so", _filename); - if (!filename) + if (asprintf(&filename, "%s.so", _filename) < 0) return NULL; handle = dlopen(filename, RTLD_NOW|RTLD_LOCAL); free(filename); diff --git a/src/3rdparty/hwloc/src/diff.c b/src/3rdparty/hwloc/src/diff.c index 81e12c55..361fa524 100644 --- a/src/3rdparty/hwloc/src/diff.c +++ b/src/3rdparty/hwloc/src/diff.c @@ -1,5 +1,5 @@ /* - * Copyright © 2013-2022 Inria. All rights reserved. + * Copyright © 2013-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -411,6 +411,30 @@ int hwloc_topology_diff_build(hwloc_topology_t topo1, } } + if (!err) { + /* cpukinds */ + if (topo1->nr_cpukinds != topo2->nr_cpukinds) + goto roottoocomplex; + for(i=0; inr_cpukinds; i++) { + struct hwloc_internal_cpukind_s *ic1 = &topo1->cpukinds[i]; + struct hwloc_internal_cpukind_s *ic2 = &topo2->cpukinds[i]; + unsigned j; + if (!hwloc_bitmap_isequal(ic1->cpuset, ic2->cpuset) + || ic1->efficiency != ic2->efficiency + || ic1->forced_efficiency != ic2->forced_efficiency + || ic1->ranking_value != ic2->ranking_value + || ic1->nr_infos != ic2->nr_infos) + goto roottoocomplex; + for(j=0; jnr_infos; j++) { + struct hwloc_info_s *info1 = &ic1->infos[j], *info2 = &ic2->infos[j]; + if (strcmp(info1->name, info2->name) + || strcmp(info1->value, info2->value)) { + goto roottoocomplex; + } + } + } + } + return err; roottoocomplex: diff --git a/src/3rdparty/hwloc/src/memattrs.c b/src/3rdparty/hwloc/src/memattrs.c index b27ed3ec..ab945471 100644 --- a/src/3rdparty/hwloc/src/memattrs.c +++ b/src/3rdparty/hwloc/src/memattrs.c @@ -1,5 +1,5 @@ /* - * Copyright © 2020-2022 Inria. All rights reserved. + * Copyright © 2020-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -1219,24 +1219,82 @@ hwloc_get_local_numanode_objs(hwloc_topology_t topology, * Using memattrs to identify HBM/DRAM */ +enum hwloc_memory_tier_type_e { + /* WARNING: keep higher BW types first for compare_tiers_by_bw_and_type() when BW info is missing */ + HWLOC_MEMORY_TIER_HBM = 1UL<<0, + HWLOC_MEMORY_TIER_DRAM = 1UL<<1, + HWLOC_MEMORY_TIER_GPU = 1UL<<2, + HWLOC_MEMORY_TIER_SPM = 1UL<<3, /* Specific-Purpose Memory is usually HBM, we'll use BW to confirm or force*/ + HWLOC_MEMORY_TIER_NVM = 1UL<<4, + HWLOC_MEMORY_TIER_CXL = 1UL<<5 +}; +typedef unsigned long hwloc_memory_tier_type_t; +#define HWLOC_MEMORY_TIER_UNKNOWN 0UL + +static const char * hwloc_memory_tier_type_snprintf(hwloc_memory_tier_type_t type) +{ + switch (type) { + case HWLOC_MEMORY_TIER_DRAM: return "DRAM"; + case HWLOC_MEMORY_TIER_HBM: return "HBM"; + case HWLOC_MEMORY_TIER_GPU: return "GPUMemory"; + case HWLOC_MEMORY_TIER_SPM: return "SPM"; + case HWLOC_MEMORY_TIER_NVM: return "NVM"; + case HWLOC_MEMORY_TIER_CXL: + case HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_DRAM: return "CXL-DRAM"; + case HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_HBM: return "CXL-HBM"; + case HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_GPU: return "CXL-GPUMemory"; + case HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_SPM: return "CXL-SPM"; + case HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_NVM: return "CXL-NVM"; + default: return NULL; + } +} + +static hwloc_memory_tier_type_t hwloc_memory_tier_type_sscanf(const char *name) +{ + if (!strcasecmp(name, "DRAM")) + return HWLOC_MEMORY_TIER_DRAM; + if (!strcasecmp(name, "HBM")) + return HWLOC_MEMORY_TIER_HBM; + if (!strcasecmp(name, "GPUMemory")) + return HWLOC_MEMORY_TIER_GPU; + if (!strcasecmp(name, "SPM")) + return HWLOC_MEMORY_TIER_SPM; + if (!strcasecmp(name, "NVM")) + return HWLOC_MEMORY_TIER_NVM; + if (!strcasecmp(name, "CXL-DRAM")) + return HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_DRAM; + if (!strcasecmp(name, "CXL-HBM")) + return HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_HBM; + if (!strcasecmp(name, "CXL-GPUMemory")) + return HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_GPU; + if (!strcasecmp(name, "CXL-SPM")) + return HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_SPM; + if (!strcasecmp(name, "CXL-NVM")) + return HWLOC_MEMORY_TIER_CXL|HWLOC_MEMORY_TIER_NVM; + return 0; +} + +/* factorized tier, grouping multiple nodes */ struct hwloc_memory_tier_s { - hwloc_obj_t node; - uint64_t local_bw; - enum hwloc_memory_tier_type_e { - /* warning the order is important for guess_memory_tiers() after qsort() */ - HWLOC_MEMORY_TIER_UNKNOWN, - HWLOC_MEMORY_TIER_DRAM, - HWLOC_MEMORY_TIER_HBM, - HWLOC_MEMORY_TIER_SPM, /* Specific-Purpose Memory is usually HBM, we'll use BW to confirm */ - HWLOC_MEMORY_TIER_NVM, - HWLOC_MEMORY_TIER_GPU, - } type; + hwloc_nodeset_t nodeset; + uint64_t local_bw_min, local_bw_max; + uint64_t local_lat_min, local_lat_max; + hwloc_memory_tier_type_t type; }; -static int compare_tiers(const void *_a, const void *_b) +/* early tier discovery, one entry per node */ +struct hwloc_memory_node_info_s { + hwloc_obj_t node; + uint64_t local_bw; + uint64_t local_lat; + hwloc_memory_tier_type_t type; + unsigned rank; +}; + +static int compare_node_infos_by_type_and_bw(const void *_a, const void *_b) { - const struct hwloc_memory_tier_s *a = _a, *b = _b; - /* sort by type of tier first */ + const struct hwloc_memory_node_info_s *a = _a, *b = _b; + /* sort by type of node first */ if (a->type != b->type) return a->type - b->type; /* then by bandwidth */ @@ -1247,180 +1305,560 @@ static int compare_tiers(const void *_a, const void *_b) return 0; } -int -hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology) +static int compare_tiers_by_bw_and_type(const void *_a, const void *_b) { - struct hwloc_internal_memattr_s *imattr; - struct hwloc_memory_tier_s *tiers; - unsigned i, j, n; - const char *env; - int spm_is_hbm = -1; /* -1 will guess from BW, 0 no, 1 forced */ - int mark_dram = 1; - unsigned first_spm, first_nvm; - hwloc_uint64_t max_unknown_bw, min_spm_bw; - - env = getenv("HWLOC_MEMTIERS_GUESS"); - if (env) { - if (!strcmp(env, "none")) { - return 0; - } else if (!strcmp(env, "default")) { - /* nothing */ - } else if (!strcmp(env, "spm_is_hbm")) { - hwloc_debug("Assuming SPM-tier is HBM, ignore bandwidth\n"); - spm_is_hbm = 1; - } else if (HWLOC_SHOW_CRITICAL_ERRORS()) { - fprintf(stderr, "hwloc: Failed to recognize HWLOC_MEMTIERS_GUESS value %s\n", env); - } + const struct hwloc_memory_tier_s *a = _a, *b = _b; + /* sort by (average) BW first */ + if (a->local_bw_min && b->local_bw_min) { + if (a->local_bw_min + a->local_bw_max > b->local_bw_min + b->local_bw_max) + return -1; + else if (a->local_bw_min + a->local_bw_max < b->local_bw_min + b->local_bw_max) + return 1; } + /* then by tier type */ + if (a->type != b->type) + return a->type - b->type; + return 0; +} - imattr = &topology->memattrs[HWLOC_MEMATTR_ID_BANDWIDTH]; - - if (!(imattr->iflags & HWLOC_IMATTR_FLAG_CACHE_VALID)) - hwloc__imattr_refresh(topology, imattr); +static struct hwloc_memory_tier_s * +hwloc__group_memory_tiers(hwloc_topology_t topology, + unsigned *nr_tiers_p) +{ + struct hwloc_internal_memattr_s *imattr_bw, *imattr_lat; + struct hwloc_memory_node_info_s *nodeinfos; + struct hwloc_memory_tier_s *tiers; + unsigned nr_tiers; + float bw_threshold = 0.1; + float lat_threshold = 0.1; + const char *env; + unsigned i, j, n; n = hwloc_get_nbobjs_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE); assert(n); - tiers = malloc(n * sizeof(*tiers)); - if (!tiers) - return -1; + env = getenv("HWLOC_MEMTIERS_BANDWIDTH_THRESHOLD"); + if (env) + bw_threshold = atof(env); + + env = getenv("HWLOC_MEMTIERS_LATENCY_THRESHOLD"); + if (env) + lat_threshold = atof(env); + + imattr_bw = &topology->memattrs[HWLOC_MEMATTR_ID_BANDWIDTH]; + imattr_lat = &topology->memattrs[HWLOC_MEMATTR_ID_LATENCY]; + + if (!(imattr_bw->iflags & HWLOC_IMATTR_FLAG_CACHE_VALID)) + hwloc__imattr_refresh(topology, imattr_bw); + if (!(imattr_lat->iflags & HWLOC_IMATTR_FLAG_CACHE_VALID)) + hwloc__imattr_refresh(topology, imattr_lat); + + nodeinfos = malloc(n * sizeof(*nodeinfos)); + if (!nodeinfos) + return NULL; for(i=0; isubtype && !strcmp(node->subtype, "GPUMemory")) - tiers[i].type = HWLOC_MEMORY_TIER_GPU; + nodeinfos[i].type = HWLOC_MEMORY_TIER_GPU; + else if (daxtype && !strcmp(daxtype, "NVM")) + nodeinfos[i].type = HWLOC_MEMORY_TIER_NVM; + else if (daxtype && !strcmp(daxtype, "SPM")) + nodeinfos[i].type = HWLOC_MEMORY_TIER_SPM; + /* add CXL flag */ + if (hwloc_obj_get_info_by_name(node, "CXLDevice") != NULL) { + /* CXL is always SPM for now. HBM and DRAM not possible here yet. + * Hence remove all but NVM first. + */ + nodeinfos[i].type &= HWLOC_MEMORY_TIER_NVM; + nodeinfos[i].type |= HWLOC_MEMORY_TIER_CXL; + } - if (spm_is_hbm == -1) { - for(j=0; jnr_targets; j++) - if (imattr->targets[j].obj == node) { - imtg = &imattr->targets[j]; - break; - } - if (imtg && !hwloc_bitmap_iszero(node->cpuset)) { - iloc.type = HWLOC_LOCATION_TYPE_CPUSET; - iloc.location.cpuset = node->cpuset; - imi = hwloc__memattr_target_get_initiator(imtg, &iloc, 0); - if (imi) - tiers[i].local_bw = imi->value; + /* get local bandwidth */ + imtg = NULL; + for(j=0; jnr_targets; j++) + if (imattr_bw->targets[j].obj == node) { + imtg = &imattr_bw->targets[j]; + break; + } + if (imtg && !hwloc_bitmap_iszero(node->cpuset)) { + struct hwloc_internal_memattr_initiator_s *imi; + iloc.type = HWLOC_LOCATION_TYPE_CPUSET; + iloc.location.cpuset = node->cpuset; + imi = hwloc__memattr_target_get_initiator(imtg, &iloc, 0); + if (imi) + nodeinfos[i].local_bw = imi->value; + } + /* get local latency */ + imtg = NULL; + for(j=0; jnr_targets; j++) + if (imattr_lat->targets[j].obj == node) { + imtg = &imattr_lat->targets[j]; + break; + } + if (imtg && !hwloc_bitmap_iszero(node->cpuset)) { + struct hwloc_internal_memattr_initiator_s *imi; + iloc.type = HWLOC_LOCATION_TYPE_CPUSET; + iloc.location.cpuset = node->cpuset; + imi = hwloc__memattr_target_get_initiator(imtg, &iloc, 0); + if (imi) + nodeinfos[i].local_lat = imi->value; + } + } + + /* Sort nodes. + * We could also sort by the existing subtype. + * KNL is the only case where subtypes are set in backends, but we set memattrs as well there. + * Also HWLOC_MEMTIERS_REFRESH would be a special value to ignore existing subtypes. + */ + hwloc_debug("Sorting memory node infos...\n"); + qsort(nodeinfos, n, sizeof(*nodeinfos), compare_node_infos_by_type_and_bw); +#ifdef HWLOC_DEBUG + for(i=0; ilogical_index, nodeinfos[i].node->os_index, + nodeinfos[i].type, + (unsigned long long) nodeinfos[i].local_bw, + (unsigned long long) nodeinfos[i].local_lat); +#endif + /* now we have UNKNOWN nodes (sorted by BW only), then known ones */ + + /* iterate among them and add a rank value. + * start from rank 0 and switch to next rank when the type changes or when the BW or latendy difference is > threshold */ + hwloc_debug("Starting memory tier #0 and iterating over nodes...\n"); + nodeinfos[0].rank = 0; + for(i=1; ilogical_index, nodeinfos[i].node->os_index); + nodeinfos[i].rank++; + continue; + } + /* comparing bandwidth */ + if (nodeinfos[i].local_bw && nodeinfos[i-1].local_bw) { + float bw_ratio = (float)nodeinfos[i].local_bw/(float)nodeinfos[i-1].local_bw; + if (bw_ratio < 1.) + bw_ratio = 1./bw_ratio; + if (bw_ratio > 1.0 + bw_threshold) { + nodeinfos[i].rank++; + hwloc_debug(" Switching to memory tier #%u starting with node L#%u P#%u because of bandwidth\n", + nodeinfos[i].rank, nodeinfos[i].node->logical_index, nodeinfos[i].node->os_index); + continue; + } + } + /* comparing latency */ + if (nodeinfos[i].local_lat && nodeinfos[i-1].local_lat) { + float lat_ratio = (float)nodeinfos[i].local_lat/(float)nodeinfos[i-1].local_lat; + if (lat_ratio < 1.) + lat_ratio = 1./lat_ratio; + if (lat_ratio > 1.0 + lat_threshold) { + hwloc_debug(" Switching to memory tier #%u starting with node L#%u P#%u because of latency\n", + nodeinfos[i].rank, nodeinfos[i].node->logical_index, nodeinfos[i].node->os_index); + nodeinfos[i].rank++; + continue; } } } + /* FIXME: if there are cpuset-intersecting nodes in same tier, split again? */ + hwloc_debug(" Found %u tiers total\n", nodeinfos[n-1].rank + 1); - /* sort tiers */ - qsort(tiers, n, sizeof(*tiers), compare_tiers); - hwloc_debug("Sorting memory tiers...\n"); - for(i=0; ilogical_index, tiers[i].node->os_index, - tiers[i].type, (unsigned long long) tiers[i].local_bw); - - /* now we have UNKNOWN tiers (sorted by BW), then SPM tiers (sorted by BW), then NVM, then GPU */ - - /* iterate over UNKNOWN tiers, and find their BW */ + /* now group nodeinfos into factorized tiers */ + nr_tiers = nodeinfos[n-1].rank + 1; + tiers = calloc(nr_tiers, sizeof(*tiers)); + if (!tiers) + goto out_with_nodeinfos; + for(i=0; i HWLOC_MEMORY_TIER_UNKNOWN) - break; - } - first_spm = i; - /* get max BW from first */ - if (first_spm > 0) - max_unknown_bw = tiers[0].local_bw; - else - max_unknown_bw = 0; - - /* there are no DRAM or HBM tiers yet */ - - /* iterate over SPM tiers, and find their BW */ - for(i=first_spm; i HWLOC_MEMORY_TIER_SPM) - break; - } - first_nvm = i; - /* get min BW from last */ - if (first_nvm > first_spm) - min_spm_bw = tiers[first_nvm-1].local_bw; - else - min_spm_bw = 0; - - /* FIXME: if there's more than 10% between some sets of nodes inside a tier, split it? */ - /* FIXME: if there are cpuset-intersecting nodes in same tier, abort? */ - - if (spm_is_hbm == -1) { - /* if we have BW for all SPM and UNKNOWN - * and all SPM BW are 2x superior to all UNKNOWN BW - */ - hwloc_debug("UNKNOWN-memory-tier max bandwidth %llu\n", (unsigned long long) max_unknown_bw); - hwloc_debug("SPM-memory-tier min bandwidth %llu\n", (unsigned long long) min_spm_bw); - if (max_unknown_bw > 0 && min_spm_bw > 0 && max_unknown_bw*2 < min_spm_bw) { - hwloc_debug("assuming SPM means HBM and !SPM means DRAM since bandwidths are very different\n"); - spm_is_hbm = 1; - } else { - hwloc_debug("cannot assume SPM means HBM\n"); - spm_is_hbm = 0; - } + unsigned rank = nodeinfos[i].rank; + assert(rank < nr_tiers); + hwloc_bitmap_set(tiers[rank].nodeset, nodeinfos[i].node->os_index); + assert(tiers[rank].type == HWLOC_MEMORY_TIER_UNKNOWN + || tiers[rank].type == nodeinfos[i].type); + tiers[rank].type = nodeinfos[i].type; + /* nodeinfos are sorted in BW order, no need to compare */ + if (!tiers[rank].local_bw_min) + tiers[rank].local_bw_min = nodeinfos[i].local_bw; + tiers[rank].local_bw_max = nodeinfos[i].local_bw; + /* compare latencies to update min/max */ + if (!tiers[rank].local_lat_min || nodeinfos[i].local_lat < tiers[rank].local_lat_min) + tiers[rank].local_lat_min = nodeinfos[i].local_lat; + if (!tiers[rank].local_lat_max || nodeinfos[i].local_lat > tiers[rank].local_lat_max) + tiers[rank].local_lat_max = nodeinfos[i].local_lat; } - if (spm_is_hbm) { - for(i=0; isubtype) /* don't overwrite the existing subtype */ - continue; - switch (tiers[i].type) { - case HWLOC_MEMORY_TIER_DRAM: - if (mark_dram) - type = "DRAM"; - break; - case HWLOC_MEMORY_TIER_HBM: - type = "HBM"; - break; - case HWLOC_MEMORY_TIER_SPM: - type = "SPM"; - break; - case HWLOC_MEMORY_TIER_NVM: - type = "NVM"; - break; - default: - /* GPU memory is already marked with subtype="GPUMemory", - * UNKNOWN doesn't deserve any subtype - */ - break; - } - if (type) { - hwloc_debug("Marking node L#%u P#%u as %s\n", tiers[i].node->logical_index, tiers[i].node->os_index, type); - tiers[i].node->subtype = strdup(type); - } - } + free(nodeinfos); + *nr_tiers_p = nr_tiers; + return tiers; + out_with_tiers: + for(i=0; ilocal_bw_min || !tier2->local_bw_min) { + hwloc_debug(" Missing BW info\n"); + return -1; + } + + /* reorder tiers by BW */ + if (tier1->local_bw_min > tier2->local_bw_min) { + tmp = tier1; tier1 = tier2; tier2 = tmp; + } + /* tier1 < tier2 */ + + hwloc_debug(" tier1 BW %llu-%llu vs tier2 BW %llu-%llu\n", + (unsigned long long) tier1->local_bw_min, + (unsigned long long) tier1->local_bw_max, + (unsigned long long) tier2->local_bw_min, + (unsigned long long) tier2->local_bw_max); + if (tier2->local_bw_min <= tier1->local_bw_max * 2) { + /* tier2 BW isn't 2x tier1, we cannot guess HBM */ + hwloc_debug(" BW difference isn't >2x\n"); + return -1; + } + /* tier2 BW is >2x tier1 */ + + if ((flags & HWLOC_GUESS_MEMTIERS_FLAG_NODE0_IS_DRAM) + && hwloc_bitmap_isset(tier2->nodeset, 0)) { + /* node0 is not DRAM, and we assume that's not possible */ + hwloc_debug(" node0 shouldn't have HBM BW\n"); + return -1; + } + + /* assume tier1 == DRAM and tier2 == HBM */ + tier1->type = HWLOC_MEMORY_TIER_DRAM; + tier2->type = HWLOC_MEMORY_TIER_HBM; + hwloc_debug(" Success\n"); + return 0; +} + +static int +hwloc__guess_memory_tiers_types(hwloc_topology_t topology __hwloc_attribute_unused, + unsigned nr_tiers, + struct hwloc_memory_tier_s *tiers) +{ + unsigned long flags; + const char *env; + unsigned nr_unknown, nr_spm; + struct hwloc_memory_tier_s *unknown_tier[2], *spm_tier; + unsigned i; + + flags = 0; + env = getenv("HWLOC_MEMTIERS_GUESS"); + if (env) { + if (!strcmp(env, "none")) + return 0; + /* by default, we don't guess anything unsure */ + if (!strcmp(env, "all")) + /* enable all typical cases */ + flags = ~0UL; + if (strstr(env, "spm_is_hbm")) { + hwloc_debug("Assuming SPM-tier is HBM, ignore bandwidth\n"); + flags |= HWLOC_GUESS_MEMTIERS_FLAG_SPM_IS_HBM; + } + if (strstr(env, "node0_is_dram")) { + hwloc_debug("Assuming node0 is DRAM\n"); + flags |= HWLOC_GUESS_MEMTIERS_FLAG_NODE0_IS_DRAM; + } + } + + if (nr_tiers == 1) + /* Likely DRAM only, but could also be HBM-only in non-SPM mode. + * We cannot be sure, but it doesn't matter since there's a single tier. + */ + return 0; + + nr_unknown = nr_spm = 0; + unknown_tier[0] = unknown_tier[1] = spm_tier = NULL; + for(i=0; i DRAM or HBM? HBM won't be SPM on HBM-only CPUs + * unknown + CXL DRAM => DRAM or HBM? + */ + if (nr_unknown == 2 && !nr_spm) { + /* 2 unknown, could be DRAM + non-SPM HBM */ + hwloc_debug(" Trying to guess 2 unknown tiers using BW\n"); + hwloc__guess_dram_hbm_tiers(unknown_tier[0], unknown_tier[1], flags); + } else if (nr_unknown == 1 && nr_spm == 1) { + /* 1 unknown + 1 SPM, could be DRAM + SPM HBM */ + hwloc_debug(" Trying to guess 1 unknown + 1 SPM tiers using BW\n"); + hwloc__guess_dram_hbm_tiers(unknown_tier[0], spm_tier, flags); + } + + if (flags & HWLOC_GUESS_MEMTIERS_FLAG_SPM_IS_HBM) { + /* force mark SPM as HBM */ + for(i=0; ios_index)) { + const char *subtype = hwloc_memory_tier_type_snprintf(tiers[j].type); + if (!node->subtype || force) { /* don't overwrite the existing subtype unless forced */ + if (subtype) { /* don't set a subtype for unknown tiers */ + hwloc_debug(" marking node L#%u P#%u as %s (was %s)\n", node->logical_index, node->os_index, subtype, node->subtype); + free(node->subtype); + node->subtype = strdup(subtype); + } + } else + hwloc_debug(" node L#%u P#%u already marked as %s, not setting %s\n", + node->logical_index, node->os_index, node->subtype, subtype); + if (nr_tiers > 1) { + char tmp[20]; + snprintf(tmp, sizeof(tmp), "%u", j); + hwloc__add_info_nodup(&node->infos, &node->infos_count, "MemoryTier", tmp, 1); + } + break; /* each node is in a single tier */ + } + } + } +} + +int +hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology, int force_subtype) +{ + struct hwloc_memory_tier_s *tiers; + unsigned nr_tiers; + unsigned i; + const char *env; + + env = getenv("HWLOC_MEMTIERS"); + if (env) { + if (!strcmp(env, "none")) + goto out; + tiers = hwloc__force_memory_tiers(topology, &nr_tiers, env); + if (tiers) { + assert(nr_tiers > 0); + force_subtype = 1; + goto ready; + } + } + + tiers = hwloc__group_memory_tiers(topology, &nr_tiers); + if (!tiers) + goto out; + + hwloc__guess_memory_tiers_types(topology, nr_tiers, tiers); + + /* sort tiers by BW first, then by type */ + hwloc_debug("Sorting memory tiers...\n"); + qsort(tiers, nr_tiers, sizeof(*tiers), compare_tiers_by_bw_and_type); + + ready: +#ifdef HWLOC_DEBUG + for(i=0; itype; + + if (type == HWLOC_OBJ_GROUP) { + if (sattr->depth == (unsigned)-1) + sattr->depth = type_count[HWLOC_OBJ_GROUP]--; + + } else if (hwloc__obj_type_is_cache(type)) { + if (!sattr->memorysize) { + if (1 == sattr->depth) + /* 32KiB in L1 */ + sattr->memorysize = 32*1024; + else + /* *4 at each level, starting from 1MiB for L2, unified */ + sattr->memorysize = 256ULL*1024 << (2*sattr->depth); + } + + } else if (type == HWLOC_OBJ_NUMANODE && !sattr->memorysize) { + /* 1GiB in memory nodes. */ + sattr->memorysize = 1024*1024*1024; + } +} + /* frees level until arity = 0 */ static void hwloc_synthetic_free_levels(struct hwloc_synthetic_backend_data_s *data) @@ -465,6 +494,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, data->level[0].indexes.string = NULL; data->level[0].indexes.array = NULL; data->level[0].attr.memorysize = 0; + data->level[0].attr.memorysidecachesize = 0; data->level[0].attached = NULL; type_count[HWLOC_OBJ_MACHINE] = 1; if (*description == '(') { @@ -514,6 +544,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, if (attached) { attached->attr.type = type; attached->attr.memorysize = 0; + attached->attr.memorysidecachesize = 0; /* attached->attr.depth and .cachetype unused */ attached->next = NULL; pprev = &data->level[count-1].attached; @@ -601,7 +632,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, } if (!item) { if (verbose) - fprintf(stderr,"Synthetic string with disallow 0 number of objects at '%s'\n", pos); + fprintf(stderr,"Synthetic string with disallowed 0 number of objects at '%s'\n", pos); errno = EINVAL; goto error; } @@ -611,6 +642,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, data->level[count].indexes.string = NULL; data->level[count].indexes.array = NULL; data->level[count].attr.memorysize = 0; + data->level[count].attr.memorysidecachesize = 0; if (*next_pos == '(') { err = hwloc_synthetic_parse_attrs(next_pos+1, &next_pos, &data->level[count].attr, &data->level[count].indexes, verbose); if (err < 0) @@ -796,6 +828,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, data->level[1].indexes.string = NULL; data->level[1].indexes.array = NULL; data->level[1].attr.memorysize = 0; + data->level[1].attr.memorysidecachesize = 0; data->level[1].totalwidth = data->level[0].totalwidth; /* update arity to insert a single NUMA node per parent */ data->level[1].arity = data->level[0].arity; @@ -803,30 +836,14 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, count++; } + /* set default attributes that depend on the depth/hierarchy of levels */ for (i=0; ilevel[i]; - hwloc_obj_type_t type = curlevel->attr.type; - - if (type == HWLOC_OBJ_GROUP) { - if (curlevel->attr.depth == (unsigned)-1) - curlevel->attr.depth = type_count[HWLOC_OBJ_GROUP]--; - - } else if (hwloc__obj_type_is_cache(type)) { - if (!curlevel->attr.memorysize) { - if (1 == curlevel->attr.depth) - /* 32KiB in L1 */ - curlevel->attr.memorysize = 32*1024; - else - /* *4 at each level, starting from 1MiB for L2, unified */ - curlevel->attr.memorysize = 256ULL*1024 << (2*curlevel->attr.depth); - } - - } else if (type == HWLOC_OBJ_NUMANODE && !curlevel->attr.memorysize) { - /* 1GiB in memory nodes. */ - curlevel->attr.memorysize = 1024*1024*1024; - } - - hwloc_synthetic_process_indexes(data, &data->level[i].indexes, data->level[i].totalwidth, verbose); + hwloc_synthetic_set_default_attrs(&curlevel->attr, type_count); + for(attached = curlevel->attached; attached != NULL; attached = attached->next) + hwloc_synthetic_set_default_attrs(&attached->attr, type_count); + hwloc_synthetic_process_indexes(data, &curlevel->indexes, curlevel->totalwidth, verbose); } hwloc_synthetic_process_indexes(data, &data->numa_attached_indexes, data->numa_attached_nr, verbose); @@ -859,6 +876,12 @@ hwloc_synthetic_set_attr(struct hwloc_synthetic_attr_s *sattr, obj->attr->numanode.page_types[0].size = 4096; obj->attr->numanode.page_types[0].count = sattr->memorysize / 4096; break; + case HWLOC_OBJ_MEMCACHE: + obj->attr->cache.depth = 1; + obj->attr->cache.linesize = 64; + obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; + obj->attr->cache.size = sattr->memorysidecachesize; + break; case HWLOC_OBJ_PACKAGE: case HWLOC_OBJ_DIE: break; @@ -926,6 +949,14 @@ hwloc_synthetic_insert_attached(struct hwloc_topology *topology, hwloc__insert_object_by_cpuset(topology, NULL, child, "synthetic:attached"); + if (attached->attr.memorysidecachesize) { + hwloc_obj_t mscachechild = hwloc_alloc_setup_object(topology, HWLOC_OBJ_MEMCACHE, HWLOC_UNKNOWN_INDEX); + mscachechild->cpuset = hwloc_bitmap_dup(set); + mscachechild->nodeset = hwloc_bitmap_dup(child->nodeset); + hwloc_synthetic_set_attr(&attached->attr, mscachechild); + hwloc__insert_object_by_cpuset(topology, NULL, mscachechild, "synthetic:attached:mscache"); + } + hwloc_synthetic_insert_attached(topology, data, attached->next, set); } @@ -977,6 +1008,14 @@ hwloc__look_synthetic(struct hwloc_topology *topology, hwloc_synthetic_set_attr(&curlevel->attr, obj); hwloc__insert_object_by_cpuset(topology, NULL, obj, "synthetic"); + + if (type == HWLOC_OBJ_NUMANODE && curlevel->attr.memorysidecachesize) { + hwloc_obj_t mscachechild = hwloc_alloc_setup_object(topology, HWLOC_OBJ_MEMCACHE, HWLOC_UNKNOWN_INDEX); + mscachechild->cpuset = hwloc_bitmap_dup(set); + mscachechild->nodeset = hwloc_bitmap_dup(obj->nodeset); + hwloc_synthetic_set_attr(&curlevel->attr, mscachechild); + hwloc__insert_object_by_cpuset(topology, NULL, mscachechild, "synthetic:mscache"); + } } hwloc_synthetic_insert_attached(topology, data, curlevel->attached, set); @@ -1217,6 +1256,7 @@ hwloc__export_synthetic_indexes(hwloc_obj_t *level, unsigned total, static int hwloc__export_synthetic_obj_attr(struct hwloc_topology * topology, + unsigned long flags, hwloc_obj_t obj, char *buffer, size_t buflen) { @@ -1224,6 +1264,7 @@ hwloc__export_synthetic_obj_attr(struct hwloc_topology * topology, const char * prefix = "("; char cachesize[64] = ""; char memsize[64] = ""; + char memorysidecachesize[64] = ""; int needindexes = 0; if (hwloc__obj_type_is_cache(obj->type) && obj->attr->cache.size) { @@ -1236,6 +1277,19 @@ hwloc__export_synthetic_obj_attr(struct hwloc_topology * topology, prefix, (unsigned long long) obj->attr->numanode.local_memory); prefix = separator; } + if (obj->type == HWLOC_OBJ_NUMANODE && !(flags & HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1)) { + hwloc_obj_t memorysidecache = obj->parent; + hwloc_uint64_t size = 0; + while (memorysidecache && memorysidecache->type == HWLOC_OBJ_MEMCACHE) { + size += memorysidecache->attr->cache.size; + memorysidecache = memorysidecache->parent; + } + if (size) { + snprintf(memorysidecachesize, sizeof(memorysidecachesize), "%smemorysidecachesize=%llu", + prefix, (unsigned long long) size); + prefix = separator; + } + } if (!obj->logical_index /* only display indexes once per level (not for non-first NUMA children, etc.) */ && (obj->type == HWLOC_OBJ_PU || obj->type == HWLOC_OBJ_NUMANODE)) { hwloc_obj_t cur = obj; @@ -1247,12 +1301,12 @@ hwloc__export_synthetic_obj_attr(struct hwloc_topology * topology, cur = cur->next_cousin; } } - if (*cachesize || *memsize || needindexes) { + if (*cachesize || *memsize || *memorysidecachesize || needindexes) { ssize_t tmplen = buflen; char *tmp = buffer; int res, ret = 0; - res = hwloc_snprintf(tmp, tmplen, "%s%s%s", cachesize, memsize, needindexes ? "" : ")"); + res = hwloc_snprintf(tmp, tmplen, "%s%s%s%s", cachesize, memsize, memorysidecachesize, needindexes ? "" : ")"); if (hwloc__export_synthetic_update_status(&ret, &tmp, &tmplen, res) < 0) return -1; @@ -1326,7 +1380,7 @@ hwloc__export_synthetic_obj(struct hwloc_topology * topology, unsigned long flag if (!(flags & HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)) { /* obj attributes */ - res = hwloc__export_synthetic_obj_attr(topology, obj, tmp, tmplen); + res = hwloc__export_synthetic_obj_attr(topology, flags, obj, tmp, tmplen); if (hwloc__export_synthetic_update_status(&ret, &tmp, &tmplen, res) < 0) return -1; } @@ -1351,7 +1405,7 @@ hwloc__export_synthetic_memory_children(struct hwloc_topology * topology, unsign if (flags & HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1) { /* v1: export a single NUMA child */ - if (parent->memory_arity > 1 || mchild->type != HWLOC_OBJ_NUMANODE) { + if (parent->memory_arity > 1) { /* not supported */ if (verbose) fprintf(stderr, "Cannot export to synthetic v1 if multiple memory children are attached to the same location.\n"); @@ -1362,6 +1416,9 @@ hwloc__export_synthetic_memory_children(struct hwloc_topology * topology, unsign if (needprefix) hwloc__export_synthetic_add_char(&ret, &tmp, &tmplen, ' '); + /* ignore memcaches and export the NUMA node */ + while (mchild->type != HWLOC_OBJ_NUMANODE) + mchild = mchild->memory_first_child; res = hwloc__export_synthetic_obj(topology, flags, mchild, 1, tmp, tmplen); if (hwloc__export_synthetic_update_status(&ret, &tmp, &tmplen, res) < 0) return -1; @@ -1369,16 +1426,25 @@ hwloc__export_synthetic_memory_children(struct hwloc_topology * topology, unsign } while (mchild) { - /* FIXME: really recurse to export memcaches and numanode, + /* The core doesn't support shared memcache for now (because ACPI and Linux don't). + * So, for each mchild here, recurse only in the first children at each level. + * + * FIXME: whenever supported by the core, really recurse to export memcaches and numanode, * but it requires clever parsing of [ memcache [numa] [numa] ] during import, * better attaching of things to describe the hierarchy. */ hwloc_obj_t numanode = mchild; - /* only export the first NUMA node leaf of each memory child - * FIXME: This assumes mscache aren't shared between nodes, that's true in current platforms + /* Only export the first NUMA node leaf of each memory child. + * Memcaches are ignored here, they will be summed and exported as a single attribute + * of the NUMA node in hwloc__export_synthetic_obj(). */ while (numanode && numanode->type != HWLOC_OBJ_NUMANODE) { - assert(numanode->arity == 1); + if (verbose && numanode->memory_arity > 1) { + static int warned = 0; + if (!warned) + fprintf(stderr, "Ignoring non-first memory children at non-first level of memory hierarchy.\n"); + warned = 1; + } numanode = numanode->memory_first_child; } assert(numanode); /* there's always a numanode at the bottom of the memory tree */ @@ -1511,17 +1577,21 @@ hwloc_topology_export_synthetic(struct hwloc_topology * topology, if (flags & HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1) { /* v1 requires all NUMA at the same level */ - hwloc_obj_t node; + hwloc_obj_t node, parent; signed pdepth; node = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 0); assert(node); - assert(hwloc__obj_type_is_normal(node->parent->type)); /* only depth-1 memory children for now */ - pdepth = node->parent->depth; + parent = node->parent; + while (!hwloc__obj_type_is_normal(parent->type)) + parent = parent->parent; + pdepth = parent->depth; while ((node = node->next_cousin) != NULL) { - assert(hwloc__obj_type_is_normal(node->parent->type)); /* only depth-1 memory children for now */ - if (node->parent->depth != pdepth) { + parent = node->parent; + while (!hwloc__obj_type_is_normal(parent->type)) + parent = parent->parent; + if (parent->depth != pdepth) { if (verbose) fprintf(stderr, "Cannot export to synthetic v1 if memory is attached to parents at different depths.\n"); errno = EINVAL; @@ -1534,7 +1604,7 @@ hwloc_topology_export_synthetic(struct hwloc_topology * topology, if (!(flags & HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)) { /* obj attributes */ - res = hwloc__export_synthetic_obj_attr(topology, obj, tmp, tmplen); + res = hwloc__export_synthetic_obj_attr(topology, flags, obj, tmp, tmplen); if (res > 0) needprefix = 1; if (hwloc__export_synthetic_update_status(&ret, &tmp, &tmplen, res) < 0) diff --git a/src/3rdparty/hwloc/src/topology-windows.c b/src/3rdparty/hwloc/src/topology-windows.c index 20b617a9..e187bb12 100644 --- a/src/3rdparty/hwloc/src/topology-windows.c +++ b/src/3rdparty/hwloc/src/topology-windows.c @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -367,7 +367,7 @@ hwloc_win_get_processor_groups(void) if (nr_processor_groups > 1 && SIZEOF_VOID_P == 4) { if (HWLOC_SHOW_ALL_ERRORS()) - fprintf(stderr, "hwloc: multiple processor groups found on 32bits Windows, topology may be invalid/incomplete.\n"); + fprintf(stderr, "hwloc/windows: multiple processor groups found on 32bits Windows, topology may be invalid/incomplete.\n"); } length = 0; @@ -987,7 +987,11 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta OSVERSIONINFOEX osvi; char versionstr[20]; char hostname[122] = ""; - unsigned hostname_size = sizeof(hostname); +#if !defined(__CYGWIN__) + DWORD hostname_size = sizeof(hostname); +#else + size_t hostname_size = sizeof(hostname); +#endif int has_efficiencyclass = 0; struct hwloc_win_efficiency_classes eclasses; char *env = getenv("HWLOC_WINDOWS_PROCESSOR_GROUP_OBJS"); @@ -1051,12 +1055,16 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta unsigned efficiency_class = 0; GROUP_AFFINITY *GroupMask; - /* Ignore unknown caches */ - if (procInfo->Relationship == RelationCache - && procInfo->Cache.Type != CacheUnified - && procInfo->Cache.Type != CacheData - && procInfo->Cache.Type != CacheInstruction) - continue; + if (procInfo->Relationship == RelationCache) { + if (!topology->want_some_cpu_caches) + /* TODO: check if RelationAll&~RelationCache works? */ + continue; + if (procInfo->Cache.Type != CacheUnified + && procInfo->Cache.Type != CacheData + && procInfo->Cache.Type != CacheInstruction) + /* Ignore unknown caches */ + continue; + } id = HWLOC_UNKNOWN_INDEX; switch (procInfo->Relationship) { diff --git a/src/3rdparty/hwloc/src/topology-x86.c b/src/3rdparty/hwloc/src/topology-x86.c index a1558f07..7aabd168 100644 --- a/src/3rdparty/hwloc/src/topology-x86.c +++ b/src/3rdparty/hwloc/src/topology-x86.c @@ -1,5 +1,5 @@ /* - * Copyright © 2010-2022 Inria. All rights reserved. + * Copyright © 2010-2023 Inria. All rights reserved. * Copyright © 2010-2013 Université Bordeaux * Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -38,6 +38,12 @@ struct hwloc_x86_backend_data_s { int apicid_unique; char *src_cpuiddump_path; int is_knl; + int is_hybrid; + int found_die_ids; + int found_complex_ids; + int found_unit_ids; + int found_module_ids; + int found_tile_ids; }; /************************************ @@ -80,7 +86,7 @@ cpuiddump_read(const char *dirpath, unsigned idx) cpuiddump = malloc(sizeof(*cpuiddump)); if (!cpuiddump) { - fprintf(stderr, "Failed to allocate cpuiddump for PU #%u, ignoring cpuiddump.\n", idx); + fprintf(stderr, "hwloc/x86: Failed to allocate cpuiddump for PU #%u, ignoring cpuiddump.\n", idx); goto out; } @@ -91,7 +97,7 @@ cpuiddump_read(const char *dirpath, unsigned idx) snprintf(filename, filenamelen, "%s/pu%u", dirpath, idx); file = fopen(filename, "r"); if (!file) { - fprintf(stderr, "Could not read dumped cpuid file %s, ignoring cpuiddump.\n", filename); + fprintf(stderr, "hwloc/x86: Could not read dumped cpuid file %s, ignoring cpuiddump.\n", filename); goto out_with_filename; } @@ -100,7 +106,7 @@ cpuiddump_read(const char *dirpath, unsigned idx) nr++; cpuiddump->entries = malloc(nr * sizeof(struct cpuiddump_entry)); if (!cpuiddump->entries) { - fprintf(stderr, "Failed to allocate %u cpuiddump entries for PU #%u, ignoring cpuiddump.\n", nr, idx); + fprintf(stderr, "hwloc/x86: Failed to allocate %u cpuiddump entries for PU #%u, ignoring cpuiddump.\n", nr, idx); goto out_with_file; } @@ -156,7 +162,7 @@ cpuiddump_find_by_input(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *e return; } - fprintf(stderr, "Couldn't find %x,%x,%x,%x in dumped cpuid, returning 0s.\n", + fprintf(stderr, "hwloc/x86: Couldn't find %x,%x,%x,%x in dumped cpuid, returning 0s.\n", *eax, *ebx, *ecx, *edx); *eax = 0; *ebx = 0; @@ -210,7 +216,8 @@ struct procinfo { #define TILE 4 #define MODULE 5 #define DIE 6 -#define HWLOC_X86_PROCINFO_ID_NR 7 +#define COMPLEX 7 +#define HWLOC_X86_PROCINFO_ID_NR 8 unsigned ids[HWLOC_X86_PROCINFO_ID_NR]; unsigned *otherids; unsigned levels; @@ -314,7 +321,7 @@ static void read_amd_caches_topoext(struct procinfo *infos, struct cpuiddump *sr /* the code below doesn't want any other cache yet */ assert(!infos->numcaches); - for (cachenum = 0; ; cachenum++) { + for (cachenum = 0; cachenum<16 /* guard */; cachenum++) { eax = 0x8000001d; ecx = cachenum; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); @@ -325,7 +332,7 @@ static void read_amd_caches_topoext(struct procinfo *infos, struct cpuiddump *sr cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache)); if (cache) { - for (cachenum = 0; ; cachenum++) { + for (cachenum = 0; cachenum<16 /* guard */; cachenum++) { unsigned long linesize, linepart, ways, sets; eax = 0x8000001d; ecx = cachenum; @@ -378,7 +385,7 @@ static void read_intel_caches(struct hwloc_x86_backend_data_s *data, struct proc unsigned cachenum; struct cacheinfo *cache; - for (cachenum = 0; ; cachenum++) { + for (cachenum = 0; cachenum<16 /* guard */; cachenum++) { eax = 0x04; ecx = cachenum; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); @@ -400,7 +407,7 @@ static void read_intel_caches(struct hwloc_x86_backend_data_s *data, struct proc infos->cache = tmpcaches; cache = &infos->cache[oldnumcaches]; - for (cachenum = 0; ; cachenum++) { + for (cachenum = 0; cachenum<16 /* guard */; cachenum++) { unsigned long linesize, linepart, ways, sets; eax = 0x04; ecx = cachenum; @@ -480,7 +487,7 @@ static void read_amd_cores_legacy(struct procinfo *infos, struct cpuiddump *src_ } /* AMD unit/node from CPUID 0x8000001e leaf (topoext) */ -static void read_amd_cores_topoext(struct procinfo *infos, unsigned long flags, struct cpuiddump *src_cpuiddump) +static void read_amd_cores_topoext(struct hwloc_x86_backend_data_s *data, struct procinfo *infos, unsigned long flags, struct cpuiddump *src_cpuiddump) { unsigned apic_id, nodes_per_proc = 0; unsigned eax, ebx, ecx, edx; @@ -510,6 +517,7 @@ static void read_amd_cores_topoext(struct procinfo *infos, unsigned long flags, unsigned cores_per_unit; /* coreid was obtained from read_amd_cores_legacy() earlier */ infos->ids[UNIT] = ebx & 0xff; + data->found_unit_ids = 1; cores_per_unit = ((ebx >> 8) & 0xff) + 1; hwloc_debug("topoext %08x, %u nodes, node %u, %u cores in unit %u\n", apic_id, nodes_per_proc, infos->ids[NODE], cores_per_unit, infos->ids[UNIT]); /* coreid and unitid are package-wide (core 0-15 and unit 0-7 on 16-core 2-NUMAnode processor). @@ -524,20 +532,35 @@ static void read_amd_cores_topoext(struct procinfo *infos, unsigned long flags, } } -/* Intel core/thread or even die/module/tile from CPUID 0x0b or 0x1f leaves (v1 and v2 extended topology enumeration) */ -static void read_intel_cores_exttopoenum(struct procinfo *infos, unsigned leaf, struct cpuiddump *src_cpuiddump) +/* Intel core/thread or even die/module/tile from CPUID 0x0b or 0x1f leaves (v1 and v2 extended topology enumeration) + * or AMD complex/ccd from CPUID 0x80000026 (extended CPU topology) + */ +static void read_extended_topo(struct hwloc_x86_backend_data_s *data, struct procinfo *infos, unsigned leaf, enum cpuid_type cpuid_type, struct cpuiddump *src_cpuiddump) { - unsigned level, apic_nextshift, apic_number, apic_type, apic_id = 0, apic_shift = 0, id; + unsigned level, apic_nextshift, apic_type, apic_id = 0, apic_shift = 0, id; unsigned threadid __hwloc_attribute_unused = 0; /* shut-up compiler */ unsigned eax, ebx, ecx = 0, edx; int apic_packageshift = 0; - for (level = 0; ; level++) { + for (level = 0; level<32 /* guard */; level++) { ecx = level; eax = leaf; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); - if (!eax && !ebx) - break; + /* Intel specifies that the 0x0b/0x1f loop should stop when we get "invalid domain" (0 in ecx[8:15]) + * (if so, we also get 0 in eax/ebx for invalid subleaves). + * However AMD rather says that the 0x80000026/0x0b loop should stop when we get "no thread at this level" (0 in ebx[0:15]). + * Zhaoxin follows the Intel specs but also returns "no thread at this level" for the last *valid* level (at least on KH-4000). + * From the Linux kernel code, it's very likely that AMD also returns "invalid domain" + * (because detect_extended_topology() uses that for all x86 CPUs) + * but keep with the official doc until AMD can clarify that (see #593). + */ + if (cpuid_type == amd) { + if (!(ebx & 0xffff)) + break; + } else { + if (!(ecx & 0xff00)) + break; + } apic_packageshift = eax & 0x1f; } @@ -545,47 +568,73 @@ static void read_intel_cores_exttopoenum(struct procinfo *infos, unsigned leaf, infos->otherids = malloc(level * sizeof(*infos->otherids)); if (infos->otherids) { infos->levels = level; - for (level = 0; ; level++) { + for (level = 0; level<32 /* guard */; level++) { ecx = level; eax = leaf; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); - if (!eax && !ebx) - break; + if (cpuid_type == amd) { + if (!(ebx & 0xffff)) + break; + } else { + if (!(ecx & 0xff00)) + break; + } apic_nextshift = eax & 0x1f; - apic_number = ebx & 0xffff; apic_type = (ecx & 0xff00) >> 8; apic_id = edx; id = (apic_id >> apic_shift) & ((1 << (apic_packageshift - apic_shift)) - 1); - hwloc_debug("x2APIC %08x %u: nextshift %u num %2u type %u id %2u\n", apic_id, level, apic_nextshift, apic_number, apic_type, id); + hwloc_debug("x2APIC %08x %u: nextshift %u nextnumber %2u type %u id %2u\n", + apic_id, + level, + apic_nextshift, + ebx & 0xffff /* number of threads in next level */, + apic_type, + id); infos->apicid = apic_id; infos->otherids[level] = UINT_MAX; - switch (apic_type) { - case 1: - threadid = id; - /* apic_number is the actual number of threads per core */ - break; - case 2: - infos->ids[CORE] = id; - /* apic_number is the actual number of threads per die */ - break; - case 3: - infos->ids[MODULE] = id; - /* apic_number is the actual number of threads per tile */ - break; - case 4: - infos->ids[TILE] = id; - /* apic_number is the actual number of threads per die */ - break; - case 5: - infos->ids[DIE] = id; - /* apic_number is the actual number of threads per package */ - break; - default: - hwloc_debug("x2APIC %u: unknown type %u\n", level, apic_type); - infos->otherids[level] = apic_id >> apic_shift; - break; - } - apic_shift = apic_nextshift; + switch (apic_type) { + case 1: + threadid = id; + break; + case 2: + infos->ids[CORE] = id; + break; + case 3: + if (leaf == 0x80000026) { + data->found_complex_ids = 1; + infos->ids[COMPLEX] = id; + } else { + data->found_module_ids = 1; + infos->ids[MODULE] = id; + } + break; + case 4: + if (leaf == 0x80000026) { + data->found_die_ids = 1; + infos->ids[DIE] = id; + } else { + data->found_tile_ids = 1; + infos->ids[TILE] = id; + } + break; + case 5: + if (leaf == 0x80000026) { + goto unknown_type; + } else { + data->found_die_ids = 1; + infos->ids[DIE] = id; + } + break; + case 6: + /* TODO: "DieGrp" on Intel */ + /* fallthrough */ + default: + unknown_type: + hwloc_debug("x2APIC %u: unknown type %u\n", level, apic_type); + infos->otherids[level] = apic_id >> apic_shift; + break; + } + apic_shift = apic_nextshift; } infos->apicid = apic_id; infos->ids[PKG] = apic_id >> apic_shift; @@ -704,12 +753,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns } if (highest_cpuid >= 0x1a && has_hybrid(features)) { - /* Get hybrid cpu information from cpuid 0x1a */ + /* Get hybrid cpu information from cpuid 0x1a on Intel */ eax = 0x1a; ecx = 0; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); infos->hybridcoretype = eax >> 24; infos->hybridnativemodel = eax & 0xffffff; + data->is_hybrid = 1; } /********************************************************************************* @@ -731,23 +781,30 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns * * Only needed when x2apic supported if NUMA nodes are needed. */ - read_amd_cores_topoext(infos, flags, src_cpuiddump); + read_amd_cores_topoext(data, infos, flags, src_cpuiddump); } - if ((cpuid_type == intel) && highest_cpuid >= 0x1f) { + if ((cpuid_type == amd) && highest_ext_cpuid >= 0x80000026) { + /* Get socket/die/complex/core/thread information from cpuid 0x80000026 + * (AMD Extended CPU Topology) + */ + read_extended_topo(data, infos, 0x80000026, cpuid_type, src_cpuiddump); + + } else if ((cpuid_type == intel || cpuid_type == zhaoxin) && highest_cpuid >= 0x1f) { /* Get package/die/module/tile/core/thread information from cpuid 0x1f * (Intel v2 Extended Topology Enumeration) */ - read_intel_cores_exttopoenum(infos, 0x1f, src_cpuiddump); + read_extended_topo(data, infos, 0x1f, cpuid_type, src_cpuiddump); } else if ((cpuid_type == intel || cpuid_type == amd || cpuid_type == zhaoxin) && highest_cpuid >= 0x0b && has_x2apic(features)) { /* Get package/core/thread information from cpuid 0x0b * (Intel v1 Extended Topology Enumeration) */ - read_intel_cores_exttopoenum(infos, 0x0b, src_cpuiddump); + read_extended_topo(data, infos, 0x0b, cpuid_type, src_cpuiddump); } + if (backend->topology->want_some_cpu_caches) { /************************************** * Get caches from CPU-specific leaves */ @@ -845,6 +902,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns } } } + } if (hwloc_bitmap_isset(data->apicid_set, infos->apicid)) data->apicid_unique = 0; @@ -1046,21 +1104,34 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) { if (fulldiscovery) { - /* Look for AMD Compute units inside packages */ - hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); - hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, - UNIT, "Compute Unit", - HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT, 0); - /* Look for Intel Modules inside packages */ - hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); - hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, - MODULE, "Module", - HWLOC_GROUP_KIND_INTEL_MODULE, 0); - /* Look for Intel Tiles inside packages */ - hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); - hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, - TILE, "Tile", - HWLOC_GROUP_KIND_INTEL_TILE, 0); + if (data->found_unit_ids) { + /* Look for AMD Complex inside packages */ + hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); + hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, + COMPLEX, "Complex", + HWLOC_GROUP_KIND_AMD_COMPLEX, 0); + } + if (data->found_unit_ids) { + /* Look for AMD Compute units inside packages */ + hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); + hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, + UNIT, "Compute Unit", + HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT, 0); + } + if (data->found_module_ids) { + /* Look for Intel Modules inside packages */ + hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); + hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, + MODULE, "Module", + HWLOC_GROUP_KIND_INTEL_MODULE, 0); + } + if (data->found_tile_ids) { + /* Look for Intel Tiles inside packages */ + hwloc_bitmap_copy(remaining_cpuset, complete_cpuset); + hwloc_x86_add_groups(topology, infos, nbprocs, remaining_cpuset, + TILE, "Tile", + HWLOC_GROUP_KIND_INTEL_TILE, 0); + } /* Look for unknown objects */ if (infos[one].otherids) { @@ -1094,7 +1165,8 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns } } - if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_DIE)) { + if (data->found_die_ids + && hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_DIE)) { /* Look for Intel Dies inside packages */ if (fulldiscovery) { hwloc_bitmap_t die_cpuset; @@ -1349,40 +1421,45 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long if (data->apicid_unique) { summarize(backend, infos, flags); - if (has_hybrid(features) && !(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) { + if (data->is_hybrid + && !(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) { /* use hybrid info for cpukinds */ - hwloc_bitmap_t atomset = hwloc_bitmap_alloc(); - hwloc_bitmap_t coreset = hwloc_bitmap_alloc(); - for(i=0; iapicid_unique, do nothing and return success, so that the caller does nothing either */ - return 0; } @@ -1459,7 +1536,15 @@ int hwloc_look_x86(struct hwloc_backend *backend, unsigned long flags) unsigned i; unsigned highest_cpuid; unsigned highest_ext_cpuid; - /* This stores cpuid features with the same indexing as Linux */ + /* This stores cpuid features with the same indexing as Linux: + * [0] = 0x1 edx + * [1] = 0x80000001 edx + * [4] = 0x1 ecx + * [6] = 0x80000001 ecx + * [9] = 0x7/0 ebx + * [16] = 0x7/0 ecx + * [18] = 0x7/0 edx + */ unsigned features[19] = { 0 }; struct procinfo *infos = NULL; enum cpuid_type cpuid_type = unknown; @@ -1579,6 +1664,7 @@ int hwloc_look_x86(struct hwloc_backend *backend, unsigned long flags) ecx = 0; cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump); features[9] = ebx; + features[16] = ecx; features[18] = edx; } @@ -1730,17 +1816,17 @@ hwloc_x86_check_cpuiddump_input(const char *src_cpuiddump_path, hwloc_bitmap_t s sprintf(path, "%s/hwloc-cpuid-info", src_cpuiddump_path); file = fopen(path, "r"); if (!file) { - fprintf(stderr, "Couldn't open dumped cpuid summary %s\n", path); + fprintf(stderr, "hwloc/x86: Couldn't open dumped cpuid summary %s\n", path); goto out_with_path; } if (!fgets(line, sizeof(line), file)) { - fprintf(stderr, "Found read dumped cpuid summary in %s\n", path); + fprintf(stderr, "hwloc/x86: Found read dumped cpuid summary in %s\n", path); fclose(file); goto out_with_path; } fclose(file); if (strcmp(line, "Architecture: x86\n")) { - fprintf(stderr, "Found non-x86 dumped cpuid summary in %s: %s\n", path, line); + fprintf(stderr, "hwloc/x86: Found non-x86 dumped cpuid summary in %s: %s\n", path, line); goto out_with_path; } free(path); @@ -1752,19 +1838,19 @@ hwloc_x86_check_cpuiddump_input(const char *src_cpuiddump_path, hwloc_bitmap_t s if (!*end) hwloc_bitmap_set(set, idx); else - fprintf(stderr, "Ignoring invalid dirent `%s' in dumped cpuid directory `%s'\n", + fprintf(stderr, "hwloc/x86: Ignoring invalid dirent `%s' in dumped cpuid directory `%s'\n", dirent->d_name, src_cpuiddump_path); } } closedir(dir); if (hwloc_bitmap_iszero(set)) { - fprintf(stderr, "Did not find any valid pu%%u entry in dumped cpuid directory `%s'\n", + fprintf(stderr, "hwloc/x86: Did not find any valid pu%%u entry in dumped cpuid directory `%s'\n", src_cpuiddump_path); return -1; } else if (hwloc_bitmap_last(set) != hwloc_bitmap_weight(set) - 1) { /* The x86 backends enforces contigous set of PUs starting at 0 so far */ - fprintf(stderr, "Found non-contigous pu%%u range in dumped cpuid directory `%s'\n", + fprintf(stderr, "hwloc/x86: Found non-contigous pu%%u range in dumped cpuid directory `%s'\n", src_cpuiddump_path); return -1; } @@ -1816,9 +1902,15 @@ hwloc_x86_component_instantiate(struct hwloc_topology *topology, /* default values */ data->is_knl = 0; + data->is_hybrid = 0; data->apicid_set = hwloc_bitmap_alloc(); data->apicid_unique = 1; data->src_cpuiddump_path = NULL; + data->found_die_ids = 0; + data->found_complex_ids = 0; + data->found_unit_ids = 0; + data->found_module_ids = 0; + data->found_tile_ids = 0; src_cpuiddump_path = getenv("HWLOC_CPUID_PATH"); if (src_cpuiddump_path) { @@ -1829,7 +1921,7 @@ hwloc_x86_component_instantiate(struct hwloc_topology *topology, assert(!hwloc_bitmap_iszero(set)); /* enforced by hwloc_x86_check_cpuiddump_input() */ data->nbprocs = hwloc_bitmap_weight(set); } else { - fprintf(stderr, "Ignoring dumped cpuid directory.\n"); + fprintf(stderr, "hwloc/x86: Ignoring dumped cpuid directory.\n"); } hwloc_bitmap_free(set); } diff --git a/src/3rdparty/hwloc/src/topology-xml-nolibxml.c b/src/3rdparty/hwloc/src/topology-xml-nolibxml.c index c0691962..8ea5e385 100644 --- a/src/3rdparty/hwloc/src/topology-xml-nolibxml.c +++ b/src/3rdparty/hwloc/src/topology-xml-nolibxml.c @@ -411,12 +411,12 @@ hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata, bdata->data = nbdata; if (xmlbuffer) { - nbdata->buffer = malloc(xmlbuflen+1); + nbdata->buffer = malloc(xmlbuflen); if (!nbdata->buffer) goto out_with_nbdata; - nbdata->buflen = xmlbuflen+1; + nbdata->buflen = xmlbuflen; memcpy(nbdata->buffer, xmlbuffer, xmlbuflen); - nbdata->buffer[xmlbuflen] = '\0'; + nbdata->buffer[xmlbuflen-1] = '\0'; /* make sure it's there as requested in the API */ } else { int err = hwloc_nolibxml_read_file(xmlpath, &nbdata->buffer, &nbdata->buflen); @@ -453,8 +453,9 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state, buffer = malloc(xmlbuflen); if (!buffer) goto out; - memcpy(buffer, xmlbuffer, xmlbuflen); buflen = xmlbuflen; + memcpy(buffer, xmlbuffer, xmlbuflen); + buffer[xmlbuflen-1] = '\0'; /* make sure it's there as requested in the API */ } else { ret = hwloc_nolibxml_read_file(xmlpath, &buffer, &buflen); diff --git a/src/3rdparty/hwloc/src/topology-xml.c b/src/3rdparty/hwloc/src/topology-xml.c index b1f20dbf..70006f63 100644 --- a/src/3rdparty/hwloc/src/topology-xml.c +++ b/src/3rdparty/hwloc/src/topology-xml.c @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2011, 2020 Université Bordeaux * Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -562,7 +562,13 @@ hwloc__xml_import_pagetype(hwloc_topology_t topology __hwloc_attribute_unused, s char *attrname, *attrvalue; if (state->global->next_attr(state, &attrname, &attrvalue) < 0) break; - if (!strcmp(attrname, "size")) + if (!strcmp(attrname, "info")) { + char *infoname, *infovalue; + int ret = hwloc___xml_import_info(&infoname, &infovalue, state); + if (ret < 0) + return -1; + /* ignored */ + } else if (!strcmp(attrname, "size")) size = strtoull(attrvalue, NULL, 10); else if (!strcmp(attrname, "count")) count = strtoull(attrvalue, NULL, 10); @@ -1160,6 +1166,48 @@ hwloc__xml_import_object(hwloc_topology_t topology, data->last_numanode = obj; } + /* 3.0 forward compatibility */ + if (data->version_major >= 3 && obj->type == HWLOC_OBJ_OS_DEVICE) { + /* osdev.type changed into bitmak in 3.0 */ + if (obj->attr->osdev.type & 3 /* STORAGE|MEMORY for BLOCK */) { + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_BLOCK; + } else if (obj->attr->osdev.type & 8 /* COPROC for COPROC and rsmi/nvml GPUs */) { + if (obj->subtype && (!strcmp(obj->subtype, "RSMI") || !strcmp(obj->subtype, "NVML"))) + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU; + else + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC; + } else if (obj->attr->osdev.type & 4 /* GPU for non-COPROC GPUs */) { + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU; + } else if (obj->attr->osdev.type & 32 /* OFED */) { + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_OPENFABRICS; + } else if (obj->attr->osdev.type & 16 /* NET for NET and BXI v2-fake-OFED */) { + if (obj->subtype && !strcmp(obj->subtype, "BXI")) + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_OPENFABRICS; + else + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_NETWORK; + } else if (obj->attr->osdev.type & 64 /* DMA */) { + obj->attr->osdev.type = HWLOC_OBJ_OSDEV_DMA; + } else { /* none or unknown */ + obj->attr->osdev.type = (hwloc_obj_osdev_type_t) -1; + } + /* Backend info only in root */ + if (obj->subtype && !hwloc_obj_get_info_by_name(obj, "Backend")) { + if (!strcmp(obj->subtype, "CUDA")) { + hwloc_obj_add_info(obj, "Backend", "CUDA"); + } else if (!strcmp(obj->subtype, "NVML")) { + hwloc_obj_add_info(obj, "Backend", "NVML"); + } else if (!strcmp(obj->subtype, "OpenCL")) { + hwloc_obj_add_info(obj, "Backend", "OpenCL"); + } else if (!strcmp(obj->subtype, "RSMI")) { + hwloc_obj_add_info(obj, "Backend", "RSMI"); + } else if (!strcmp(obj->subtype, "LevelZero")) { + hwloc_obj_add_info(obj, "Backend", "LevelZero"); + } else if (!strcmp(obj->subtype, "Display")) { + hwloc_obj_add_info(obj, "Backend", "GL"); + } + } + } + if (!hwloc_filter_check_keep_object(topology, obj)) { /* Ignore this object instead of inserting it. * @@ -1433,7 +1481,14 @@ hwloc__xml_v2import_distances(hwloc_topology_t topology, if (ret <= 0) break; - if (!strcmp(tag, "indexes")) + if (!strcmp(tag, "info")) { + char *infoname, *infovalue; + ret = hwloc___xml_import_info(&infoname, &infovalue, state); + if (ret < 0) + goto out_with_arrays; + /* ignored */ + continue; + } else if (!strcmp(tag, "indexes")) is_index = 1; else if (!strcmp(tag, "u64values")) is_u64values = 1; @@ -1766,6 +1821,10 @@ hwloc__xml_import_memattr(hwloc_topology_t topology, if (!strcmp(tag, "memattr_value")) { ret = hwloc__xml_import_memattr_value(topology, id, flags, &childstate); + } else if (!strcmp(tag, "info")) { + char *infoname, *infovalue; + ret = hwloc___xml_import_info(&infoname, &infovalue, &childstate); + /* ignored */ } else { if (hwloc__xml_verbose()) fprintf(stderr, "%s: memattr with unrecognized child %s\n", @@ -2094,9 +2153,10 @@ hwloc_look_xml(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus) if (ret < 0) goto failed; - if (data->version_major > 2) { + if (data->version_major > 3 + || (data->version_major == 3 && data->version_minor > 0)) { if (hwloc__xml_verbose()) - fprintf(stderr, "%s: cannot import XML version %u.%u > 2\n", + fprintf(stderr, "%s: cannot import XML version %u.%u > 3.0\n", data->msgprefix, data->version_major, data->version_minor); goto err; } @@ -2144,6 +2204,13 @@ hwloc_look_xml(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus) ret = hwloc__xml_import_cpukind(topology, &childstate); if (ret < 0) goto failed; + } else if (!strcmp(tag, "info")) { + char *infoname, *infovalue; + ret = hwloc___xml_import_info(&infoname, &infovalue, &childstate); + if (ret < 0) + goto failed; + /* move 3.x topology info back to the root object */ + hwloc_obj_add_info(topology->levels[0][0], infoname, infovalue); } else { if (hwloc__xml_verbose()) fprintf(stderr, "%s: ignoring unknown tag `%s' after root object.\n", diff --git a/src/3rdparty/hwloc/src/topology.c b/src/3rdparty/hwloc/src/topology.c index 47b4658c..9dc2b07c 100644 --- a/src/3rdparty/hwloc/src/topology.c +++ b/src/3rdparty/hwloc/src/topology.c @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2022 Inria. All rights reserved. + * Copyright © 2009-2023 Inria. All rights reserved. * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2022 IBM Corporation. All rights reserved. @@ -146,21 +146,24 @@ report_insert_error_format_obj(char *buf, size_t buflen, hwloc_obj_t obj) char typestr[64]; char *cpusetstr; char *nodesetstr = NULL; + char indexstr[64] = ""; + char groupstr[64] = ""; hwloc_obj_type_snprintf(typestr, sizeof(typestr), obj, 0); hwloc_bitmap_asprintf(&cpusetstr, obj->cpuset); + if (obj->os_index != HWLOC_UNKNOWN_INDEX) + snprintf(indexstr, sizeof(indexstr), "P#%u ", obj->os_index); + if (obj->type == HWLOC_OBJ_GROUP) + snprintf(groupstr, sizeof(groupstr), "groupkind %u-%u ", obj->attr->group.kind, obj->attr->group.subkind); if (obj->nodeset) /* may be missing during insert */ hwloc_bitmap_asprintf(&nodesetstr, obj->nodeset); - if (obj->os_index != HWLOC_UNKNOWN_INDEX) - snprintf(buf, buflen, "%s (P#%u cpuset %s%s%s)", - typestr, obj->os_index, cpusetstr, - nodesetstr ? " nodeset " : "", - nodesetstr ? nodesetstr : ""); - else - snprintf(buf, buflen, "%s (cpuset %s%s%s)", - typestr, cpusetstr, - nodesetstr ? " nodeset " : "", - nodesetstr ? nodesetstr : ""); + snprintf(buf, buflen, "%s (%s%s%s%s%scpuset %s%s%s)", + typestr, + indexstr, + obj->subtype ? "subtype " : "", obj->subtype ? obj->subtype : "", obj->subtype ? " " : "", + groupstr, + cpusetstr, + nodesetstr ? " nodeset " : "", nodesetstr ? nodesetstr : ""); free(cpusetstr); free(nodesetstr); } @@ -178,8 +181,9 @@ static void report_insert_error(hwloc_obj_t new, hwloc_obj_t old, const char *ms fprintf(stderr, "****************************************************************************\n"); fprintf(stderr, "* hwloc %s received invalid information from the operating system.\n", HWLOC_VERSION); fprintf(stderr, "*\n"); - fprintf(stderr, "* Failed with: %s\n", msg); - fprintf(stderr, "* while inserting %s at %s\n", newstr, oldstr); + fprintf(stderr, "* Failed with error: %s\n", msg); + fprintf(stderr, "* while inserting %s\n", newstr); + fprintf(stderr, "* at %s\n", oldstr); fprintf(stderr, "* coming from: %s\n", reason); fprintf(stderr, "*\n"); fprintf(stderr, "* The following FAQ entry in the hwloc documentation may help:\n"); @@ -679,7 +683,8 @@ unlink_and_free_object_and_children(hwloc_obj_t *pobj) void hwloc_free_object_and_children(hwloc_obj_t obj) { - unlink_and_free_object_and_children(&obj); + if (obj) + unlink_and_free_object_and_children(&obj); } /* Free an object, its next siblings and their children without unlinking from parent. @@ -1925,6 +1930,22 @@ hwloc_topology_alloc_group_object(struct hwloc_topology *topology) return hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, HWLOC_UNKNOWN_INDEX); } +int +hwloc_topology_free_group_object(struct hwloc_topology *topology, hwloc_obj_t obj) +{ + if (!topology->is_loaded) { + /* this could actually work, see insert() below */ + errno = EINVAL; + return -1; + } + if (topology->adopted_shmem_addr) { + errno = EPERM; + return -1; + } + hwloc_free_unlinked_object(obj); + return 0; +} + static void hwloc_propagate_symmetric_subtree(hwloc_topology_t topology, hwloc_obj_t root); static void propagate_total_memory(hwloc_obj_t obj); static void hwloc_set_group_depth(hwloc_topology_t topology); @@ -1935,7 +1956,7 @@ static int hwloc_connect_special_levels(hwloc_topology_t topology); hwloc_obj_t hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t obj) { - hwloc_obj_t res, root; + hwloc_obj_t res, root, child; int cmp; if (!topology->is_loaded) { @@ -1945,6 +1966,7 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t return NULL; } if (topology->adopted_shmem_addr) { + hwloc_free_unlinked_object(obj); errno = EPERM; return NULL; } @@ -1998,6 +2020,7 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t res = hwloc__insert_object_by_cpuset(topology, NULL, obj, NULL /* do not show errors on stdout */); } else { /* just merge root */ + hwloc_free_unlinked_object(obj); res = root; } @@ -2024,6 +2047,13 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t if (hwloc_topology_reconnect(topology, 0) < 0) return NULL; + /* Compute group total_memory. */ + res->total_memory = 0; + for_each_child(child, res) + res->total_memory += child->total_memory; + for_each_memory_child(child, res) + res->total_memory += child->total_memory; + hwloc_propagate_symmetric_subtree(topology, topology->levels[0][0]); hwloc_set_group_depth(topology); @@ -2254,11 +2284,13 @@ fixup_sets(hwloc_obj_t obj) int hwloc_obj_add_other_obj_sets(hwloc_obj_t dst, hwloc_obj_t src) { -#define ADD_OTHER_OBJ_SET(_dst, _src, _set) \ - if ((_src)->_set) { \ - if (!(_dst)->_set) \ - (_dst)->_set = hwloc_bitmap_alloc(); \ - hwloc_bitmap_or((_dst)->_set, (_dst)->_set, (_src)->_set); \ +#define ADD_OTHER_OBJ_SET(_dst, _src, _set) \ + if ((_src)->_set) { \ + if (!(_dst)->_set) \ + (_dst)->_set = hwloc_bitmap_alloc(); \ + if (!(_dst)->_set \ + || hwloc_bitmap_or((_dst)->_set, (_dst)->_set, (_src)->_set) < 0) \ + return -1; \ } ADD_OTHER_OBJ_SET(dst, src, cpuset); ADD_OTHER_OBJ_SET(dst, src, complete_cpuset); @@ -3730,6 +3762,7 @@ hwloc__topology_init (struct hwloc_topology **topologyp, hwloc__topology_filter_init(topology); + /* always initialize since we don't know flags to disable those yet */ hwloc_internal_distances_init(topology); hwloc_internal_memattrs_init(topology); hwloc_internal_cpukinds_init(topology); @@ -3942,8 +3975,12 @@ int hwloc_topology_set_cache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter) { unsigned i; - for(i=HWLOC_OBJ_L1CACHE; iis_loaded) { + errno = EBUSY; + return -1; + } + for(i=HWLOC_OBJ_L1CACHE; i<=HWLOC_OBJ_L3ICACHE; i++) + hwloc__topology_set_type_filter(topology, (hwloc_obj_type_t) i, filter); return 0; } @@ -3951,17 +3988,25 @@ int hwloc_topology_set_icache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter) { unsigned i; - for(i=HWLOC_OBJ_L1ICACHE; iis_loaded) { + errno = EBUSY; + return -1; + } + for(i=HWLOC_OBJ_L1ICACHE; i<=HWLOC_OBJ_L3ICACHE; i++) + hwloc__topology_set_type_filter(topology, (hwloc_obj_type_t) i, filter); return 0; } int hwloc_topology_set_io_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter) { - hwloc_topology_set_type_filter(topology, HWLOC_OBJ_BRIDGE, filter); - hwloc_topology_set_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, filter); - hwloc_topology_set_type_filter(topology, HWLOC_OBJ_OS_DEVICE, filter); + if (topology->is_loaded) { + errno = EBUSY; + return -1; + } + hwloc__topology_set_type_filter(topology, HWLOC_OBJ_BRIDGE, filter); + hwloc__topology_set_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, filter); + hwloc__topology_set_type_filter(topology, HWLOC_OBJ_OS_DEVICE, filter); return 0; } @@ -3982,9 +4027,12 @@ hwloc_topology_clear (struct hwloc_topology *topology) { /* no need to set to NULL after free() since callers will call setup_defaults() or just destroy the rest of the topology */ unsigned l; + + /* always destroy cpukinds/distances/memattrs since there are always initialized during init() */ hwloc_internal_cpukinds_destroy(topology); hwloc_internal_distances_destroy(topology); hwloc_internal_memattrs_destroy(topology); + hwloc_free_object_and_children(topology->levels[0][0]); hwloc_bitmap_free(topology->allowed_cpuset); hwloc_bitmap_free(topology->allowed_nodeset); @@ -4024,6 +4072,7 @@ hwloc_topology_load (struct hwloc_topology *topology) { struct hwloc_disc_status dstatus; const char *env; + unsigned i; int err; if (topology->is_loaded) { @@ -4032,8 +4081,18 @@ hwloc_topology_load (struct hwloc_topology *topology) } /* initialize envvar-related things */ - hwloc_internal_distances_prepare(topology); - hwloc_internal_memattrs_prepare(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_DISTANCES)) + hwloc_internal_distances_prepare(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS)) + hwloc_internal_memattrs_prepare(topology); + + /* check if any cpu cache filter is not NONE */ + topology->want_some_cpu_caches = 0; + for(i=HWLOC_OBJ_L1CACHE; i<=HWLOC_OBJ_L3ICACHE; i++) + if (topology->type_filter[i] != HWLOC_TYPE_FILTER_KEEP_NONE) { + topology->want_some_cpu_caches = 1; + break; + } if (getenv("HWLOC_XML_USERDATA_NOT_DECODED")) topology->userdata_not_decoded = 1; @@ -4110,23 +4169,32 @@ hwloc_topology_load (struct hwloc_topology *topology) #endif hwloc_topology_check(topology); - /* Rank cpukinds */ - hwloc_internal_cpukinds_rank(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) { + /* Rank cpukinds */ + hwloc_internal_cpukinds_rank(topology); + } - /* Mark distances objs arrays as invalid since we may have removed objects - * from the topology after adding the distances (remove_empty, etc). - * It would be hard to actually verify whether it's needed. - */ - hwloc_internal_distances_invalidate_cached_objs(topology); - /* And refresh distances so that multithreaded concurrent distances_get() - * don't refresh() concurrently (disallowed). - */ - hwloc_internal_distances_refresh(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_DISTANCES)) { + /* Mark distances objs arrays as invalid since we may have removed objects + * from the topology after adding the distances (remove_empty, etc). + * It would be hard to actually verify whether it's needed. + */ + hwloc_internal_distances_invalidate_cached_objs(topology); + /* And refresh distances so that multithreaded concurrent distances_get() + * don't refresh() concurrently (disallowed). + */ + hwloc_internal_distances_refresh(topology); + } - /* Same for memattrs */ - hwloc_internal_memattrs_need_refresh(topology); - hwloc_internal_memattrs_refresh(topology); - hwloc_internal_memattrs_guess_memory_tiers(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS)) { + int force_memtiers = (getenv("HWLOC_MEMTIERS_REFRESH") != NULL); + /* Same for memattrs */ + hwloc_internal_memattrs_need_refresh(topology); + hwloc_internal_memattrs_refresh(topology); + /* update memtiers unless XML */ + if (force_memtiers || strcmp(topology->backends->component->name, "xml")) + hwloc_internal_memattrs_guess_memory_tiers(topology, force_memtiers); + } topology->is_loaded = 1; @@ -4185,20 +4253,11 @@ restrict_object_by_cpuset(hwloc_topology_t topology, unsigned long flags, hwloc_ hwloc_bitmap_andnot(obj->cpuset, obj->cpuset, droppedcpuset); hwloc_bitmap_andnot(obj->complete_cpuset, obj->complete_cpuset, droppedcpuset); modified = 1; - } else { - if ((flags & HWLOC_RESTRICT_FLAG_REMOVE_CPULESS) - && hwloc_bitmap_iszero(obj->complete_cpuset)) { - /* we're empty, there's a NUMAnode below us, it'll be removed this time */ - modified = 1; - } - /* nodeset cannot intersect unless cpuset intersects or is empty */ - if (droppednodeset) - assert(!hwloc_bitmap_intersects(obj->complete_nodeset, droppednodeset) - || hwloc_bitmap_iszero(obj->complete_cpuset)); } - if (droppednodeset) { + if (droppednodeset && hwloc_bitmap_intersects(obj->complete_nodeset, droppednodeset)) { hwloc_bitmap_andnot(obj->nodeset, obj->nodeset, droppednodeset); hwloc_bitmap_andnot(obj->complete_nodeset, obj->complete_nodeset, droppednodeset); + modified = 1; } if (modified) { @@ -4251,20 +4310,11 @@ restrict_object_by_nodeset(hwloc_topology_t topology, unsigned long flags, hwloc hwloc_bitmap_andnot(obj->nodeset, obj->nodeset, droppednodeset); hwloc_bitmap_andnot(obj->complete_nodeset, obj->complete_nodeset, droppednodeset); modified = 1; - } else { - if ((flags & HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS) - && hwloc_bitmap_iszero(obj->complete_nodeset)) { - /* we're empty, there's a PU below us, it'll be removed this time */ - modified = 1; - } - /* cpuset cannot intersect unless nodeset intersects or is empty */ - if (droppedcpuset) - assert(!hwloc_bitmap_intersects(obj->complete_cpuset, droppedcpuset) - || hwloc_bitmap_iszero(obj->complete_nodeset)); } - if (droppedcpuset) { + if (droppedcpuset && hwloc_bitmap_intersects(obj->complete_cpuset, droppedcpuset)) { hwloc_bitmap_andnot(obj->cpuset, obj->cpuset, droppedcpuset); hwloc_bitmap_andnot(obj->complete_cpuset, obj->complete_cpuset, droppedcpuset); + modified = 1; } if (modified) { @@ -4433,13 +4483,18 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se if (hwloc_filter_levels_keep_structure(topology) < 0) /* takes care of reconnecting internally */ goto out; - /* some objects may have disappeared, we need to update distances objs arrays */ - hwloc_internal_distances_invalidate_cached_objs(topology); - hwloc_internal_memattrs_need_refresh(topology); + /* some objects may have disappeared and sets were modified, + * we need to update distances, etc */ + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_DISTANCES)) + hwloc_internal_distances_invalidate_cached_objs(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS)) + hwloc_internal_memattrs_need_refresh(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) + hwloc_internal_cpukinds_restrict(topology); + hwloc_propagate_symmetric_subtree(topology, topology->levels[0][0]); propagate_total_memory(topology->levels[0][0]); - hwloc_internal_cpukinds_restrict(topology); #ifndef HWLOC_DEBUG if (getenv("HWLOC_DEBUG_CHECK")) @@ -4527,9 +4582,12 @@ hwloc_topology_allow(struct hwloc_topology *topology, int hwloc_topology_refresh(struct hwloc_topology *topology) { - hwloc_internal_cpukinds_rank(topology); - hwloc_internal_distances_refresh(topology); - hwloc_internal_memattrs_refresh(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) + hwloc_internal_cpukinds_rank(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_DISTANCES)) + hwloc_internal_distances_refresh(topology); + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS)) + hwloc_internal_memattrs_refresh(topology); return 0; } @@ -5081,6 +5139,9 @@ hwloc_topology_check(struct hwloc_topology *topology) for(i=HWLOC_OBJ_TYPE_MIN; iis_loaded) + return; + depth = hwloc_topology_get_depth(topology); assert(!topology->modified); diff --git a/src/3rdparty/libethash/CMakeLists.txt b/src/3rdparty/libethash/CMakeLists.txt index 7df9ec86..491432a6 100644 --- a/src/3rdparty/libethash/CMakeLists.txt +++ b/src/3rdparty/libethash/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project (ethash C) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") diff --git a/src/crypto/ghostrider/CMakeLists.txt b/src/crypto/ghostrider/CMakeLists.txt index db63cfde..87050a15 100644 --- a/src/crypto/ghostrider/CMakeLists.txt +++ b/src/crypto/ghostrider/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project(GhostRider) set(HEADERS From 334753763509c5353ade35ba61732313617663c6 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 23 Mar 2024 00:46:15 +0700 Subject: [PATCH 80/87] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf89deb8..7e93d79d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v6.21.2 +- The dependencies of all prebuilt releases have been updated. Support for old Ubuntu releases has been dropped. +- [#2800](https://github.com/xmrig/xmrig/issues/2800) Fixed donation with GhostRider algorithm for builds without KawPow algorithm. +- [#3436](https://github.com/xmrig/xmrig/pull/3436) Fixed, the file log writer was not thread-safe. +- [#3450](https://github.com/xmrig/xmrig/pull/3450) Fixed RandomX crash when compiled with fortify_source. + # v6.21.1 - [#3391](https://github.com/xmrig/xmrig/pull/3391) Added support for townforge (monero fork using randomx). - [#3399](https://github.com/xmrig/xmrig/pull/3399) Fixed Zephyr mining (OpenCL). From 4ab9329dda4d0628e8ff6227c53f692da3b176bc Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 23 Mar 2024 13:38:42 +0700 Subject: [PATCH 81/87] v6.21.2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index f22dcd5b..4cb5a505 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.2-dev" +#define APP_VERSION "6.21.2" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" From 1c5786e3c581ba560354bc821b3f17e5491f846a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 23 Mar 2024 16:21:54 +0700 Subject: [PATCH 82/87] v6.21.3-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 4cb5a505..aa877312 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.2" +#define APP_VERSION "6.21.3-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 21 -#define APP_VER_PATCH 2 +#define APP_VER_PATCH 3 #ifdef _MSC_VER # if (_MSC_VER >= 1930) From 1f7e635b04aef8477379ebd990dcdb862836a5a1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 26 Mar 2024 21:46:18 +0700 Subject: [PATCH 83/87] Use internal logger for error message. --- src/base/api/Api.cpp | 13 +++++++------ src/base/api/Api.h | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index e0907a84..77f8e4aa 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2023 SChernykh - * Copyright (c) 2016-2023 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +25,8 @@ #include "base/crypto/keccak.h" #include "base/io/Env.h" #include "base/io/json/Json.h" +#include "base/io/log/Log.h" +#include "base/io/log/Tags.h" #include "base/kernel/Base.h" #include "base/tools/Chrono.h" #include "base/tools/Cvt.h" @@ -39,7 +41,6 @@ #include -#include namespace xmrig { @@ -81,8 +82,7 @@ static rapidjson::Value getResources(rapidjson::Document &doc) xmrig::Api::Api(Base *base) : m_base(base), - m_timestamp(Chrono::currentMSecsSinceEpoch()), - m_httpd(nullptr) + m_timestamp(Chrono::currentMSecsSinceEpoch()) { base->addListener(this); @@ -118,7 +118,8 @@ void xmrig::Api::start() if (!m_httpd) { m_httpd = new Httpd(m_base); if (!m_httpd->start()) { - std::cerr << "HTTP server failed to start." << std::endl; + LOG_ERR("%s " RED_BOLD("HTTP API server failed to start."), Tags::network()); + delete m_httpd; // Properly handle failure to start m_httpd = nullptr; } diff --git a/src/base/api/Api.h b/src/base/api/Api.h index 7c686ff4..f3ad04c1 100644 --- a/src/base/api/Api.h +++ b/src/base/api/Api.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2023 SChernykh - * Copyright (c) 2016-2023 XMRig , + * Copyright (c) 2018-2024 SChernykh + * Copyright (c) 2016-2024 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From c7c26d97fe6474416aaf8263d2b08ba00100f010 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:32:16 +0200 Subject: [PATCH 84/87] RandomX: check pointer sizes during JIT initialization --- src/crypto/randomx/randomx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index ed520aa8..0485d4ec 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -260,6 +260,7 @@ typedef void(randomx::JitCompilerX86::* InstructionGeneratorX86_2)(const randomx #define JIT_HANDLE(x, prev) do { \ const InstructionGeneratorX86_2 p = &randomx::JitCompilerX86::h_##x; \ + static_assert(sizeof(p) == sizeof(randomx::JitCompilerX86::engine[k]), "Pointer size mismatch"); \ memcpy(randomx::JitCompilerX86::engine + k, &p, sizeof(p)); \ } while (0) From caae7c64f0c920b633b78fb03413fdb67d459f3e Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sun, 14 Apr 2024 09:13:00 +0200 Subject: [PATCH 85/87] RandomX: correct memcpy size for JIT initialization No buffer overflow, better fix for `_FORTIFY_SOURCE` --- src/crypto/randomx/jit_compiler_a64.cpp | 2 +- src/crypto/randomx/jit_compiler_a64.hpp | 2 +- src/crypto/randomx/jit_compiler_x86.cpp | 2 +- src/crypto/randomx/jit_compiler_x86.hpp | 2 +- src/crypto/randomx/randomx.cpp | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 4bfe157e..05dac9f7 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -1078,6 +1078,6 @@ void JitCompilerA64::h_NOP(Instruction& instr, uint32_t& codePos) { } -InstructionGeneratorA64 JitCompilerA64::engine[257] = {}; +InstructionGeneratorA64 JitCompilerA64::engine[256] = {}; } diff --git a/src/crypto/randomx/jit_compiler_a64.hpp b/src/crypto/randomx/jit_compiler_a64.hpp index 15c90af8..32ff5166 100644 --- a/src/crypto/randomx/jit_compiler_a64.hpp +++ b/src/crypto/randomx/jit_compiler_a64.hpp @@ -74,7 +74,7 @@ namespace randomx { void enableWriting() const; void enableExecution() const; - static InstructionGeneratorA64 engine[257]; + static InstructionGeneratorA64 engine[256]; private: const bool hugePages; diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 78ab8b58..7f9fb3b6 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -1443,6 +1443,6 @@ namespace randomx { emitByte(0x90, code, codePos); } - alignas(64) InstructionGeneratorX86 JitCompilerX86::engine[257] = {}; + alignas(64) InstructionGeneratorX86 JitCompilerX86::engine[256] = {}; } diff --git a/src/crypto/randomx/jit_compiler_x86.hpp b/src/crypto/randomx/jit_compiler_x86.hpp index 11106b2f..15261922 100644 --- a/src/crypto/randomx/jit_compiler_x86.hpp +++ b/src/crypto/randomx/jit_compiler_x86.hpp @@ -81,7 +81,7 @@ namespace randomx { void enableWriting() const; void enableExecution() const; - alignas(64) static InstructionGeneratorX86 engine[257]; + alignas(64) static InstructionGeneratorX86 engine[256]; private: int registerUsage[RegistersCount] = {}; diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index 0485d4ec..9047293b 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -260,8 +260,7 @@ typedef void(randomx::JitCompilerX86::* InstructionGeneratorX86_2)(const randomx #define JIT_HANDLE(x, prev) do { \ const InstructionGeneratorX86_2 p = &randomx::JitCompilerX86::h_##x; \ - static_assert(sizeof(p) == sizeof(randomx::JitCompilerX86::engine[k]), "Pointer size mismatch"); \ - memcpy(randomx::JitCompilerX86::engine + k, &p, sizeof(p)); \ + memcpy(randomx::JitCompilerX86::engine + k, &p, sizeof(randomx::JitCompilerX86::engine[k])); \ } while (0) #elif (XMRIG_ARM == 8) From 57f3e9c3daad45b25d39f3011cf51b28c7511184 Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 23 Apr 2024 16:17:26 +0700 Subject: [PATCH 86/87] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e93d79d..df4440a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# v6.21.3 +- [#3462](https://github.com/xmrig/xmrig/pull/3462) RandomX: correct memcpy size for JIT initialization. + # v6.21.2 - The dependencies of all prebuilt releases have been updated. Support for old Ubuntu releases has been dropped. - [#2800](https://github.com/xmrig/xmrig/issues/2800) Fixed donation with GhostRider algorithm for builds without KawPow algorithm. From 7897f10c48899842749aa74a32d8405e0fe74af1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 23 Apr 2024 16:27:24 +0700 Subject: [PATCH 87/87] v6.21.3 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index aa877312..27f5d5de 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.21.3-dev" +#define APP_VERSION "6.21.3" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com"