Merge branch 'dev'

This commit is contained in:
XMRig 2022-06-23 20:03:29 +07:00
commit 73dc0ffb7e
No known key found for this signature in database
GPG key ID: 446A53638BE94409
142 changed files with 5967 additions and 15078 deletions

View file

@ -1,3 +1,15 @@
# v6.18.0
- [#3067](https://github.com/xmrig/xmrig/pull/3067) Monero v15 network upgrade support and more house keeping.
- Removed deprecated AstroBWTv1 and v2.
- Fixed debug GhostRider build.
- Monero v15 network upgrade support.
- Fixed ZMQ debug log.
- Improved daemon ZMQ mining stability.
- [#3054](https://github.com/xmrig/xmrig/pull/3054) Fixes for 32-bit ARM.
- [#3042](https://github.com/xmrig/xmrig/pull/3042) Fixed being unable to resume from `pause-on-battery`.
- [#3031](https://github.com/xmrig/xmrig/pull/3031) Fixed `--cpu-priority` not working sometimes.
- [#3020](https://github.com/xmrig/xmrig/pull/3020) Removed old AstroBWT algorithm.
# v6.17.0
- [#2954](https://github.com/xmrig/xmrig/pull/2954) **Dero HE fork support (`astrobwt/v2` algorithm).**
- [#2961](https://github.com/xmrig/xmrig/pull/2961) Dero HE (`astrobwt/v2`) CUDA config generator.

View file

@ -8,7 +8,6 @@ option(WITH_CN_PICO "Enable CryptoNight-Pico algorithm" ON)
option(WITH_CN_FEMTO "Enable CryptoNight-UPX2 algorithm" ON)
option(WITH_RANDOMX "Enable RandomX algorithms family" ON)
option(WITH_ARGON2 "Enable Argon2 algorithms family" ON)
option(WITH_ASTROBWT "Enable AstroBWT algorithms family" ON)
option(WITH_KAWPOW "Enable KawPow algorithms family" ON)
option(WITH_GHOSTRIDER "Enable GhostRider algorithm" ON)
option(WITH_HTTP "Enable HTTP protocol support (client/server)" ON)
@ -199,7 +198,6 @@ find_package(UV REQUIRED)
include(cmake/flags.cmake)
include(cmake/randomx.cmake)
include(cmake/argon2.cmake)
include(cmake/astrobwt.cmake)
include(cmake/kawpow.cmake)
include(cmake/ghostrider.cmake)
include(cmake/OpenSSL.cmake)

View file

@ -1,57 +0,0 @@
if (WITH_ASTROBWT)
add_definitions(/DXMRIG_ALGO_ASTROBWT)
list(APPEND HEADERS_CRYPTO
src/crypto/astrobwt/AstroBWT.h
src/crypto/astrobwt/sort_indices2.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/astrobwt/AstroBWT.cpp
src/crypto/astrobwt/sort_indices2.cpp
)
if (XMRIG_ARM)
list(APPEND HEADERS_CRYPTO
src/crypto/astrobwt/salsa20_ref/ecrypt-config.h
src/crypto/astrobwt/salsa20_ref/ecrypt-machine.h
src/crypto/astrobwt/salsa20_ref/ecrypt-portable.h
src/crypto/astrobwt/salsa20_ref/ecrypt-sync.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/astrobwt/salsa20_ref/salsa20.c
)
else()
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
set_source_files_properties(src/crypto/astrobwt/sort_indices2.cpp PROPERTIES COMPILE_FLAGS "/std:c++20")
endif()
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DASTROBWT_AVX2)
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/xmm6int/salsa20_xmm6int-avx2.c)
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/astrobwt/xmm6int/salsa20_xmm6int-avx2.c PROPERTIES COMPILE_FLAGS -mavx2)
endif()
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.asm)
else()
enable_language(ASM)
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/sha3_256_avx2.S)
endif()
endif()
list(APPEND HEADERS_CRYPTO
src/crypto/astrobwt/Salsa20.hpp
)
list(APPEND SOURCES_CRYPTO
src/crypto/astrobwt/Salsa20.cpp
)
endif()
else()
remove_definitions(/DXMRIG_ALGO_ASTROBWT)
endif()

View file

@ -2,7 +2,7 @@
HWLOC_VERSION_MAJOR="2"
HWLOC_VERSION_MINOR="7"
HWLOC_VERSION_PATCH="0"
HWLOC_VERSION_PATCH="1"
HWLOC_VERSION="${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}.${HWLOC_VERSION_PATCH}"

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
LIBRESSL_VERSION="3.4.2"
LIBRESSL_VERSION="3.5.2"
mkdir -p deps
mkdir -p deps/include

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
OPENSSL_VERSION="1.1.1m"
OPENSSL_VERSION="1.1.1o"
mkdir -p deps
mkdir -p deps/include

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
OPENSSL_VERSION="3.0.1"
OPENSSL_VERSION="3.0.3"
mkdir -p deps
mkdir -p deps/include

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
UV_VERSION="1.43.0"
UV_VERSION="1.44.1"
mkdir -p deps
mkdir -p deps/include

View file

@ -67,23 +67,6 @@ function rx()
}
function astrobwt()
{
const astrobwt = opencl_minify(addIncludes('astrobwt.cl', [ 'BWT.cl', 'salsa20.cl', 'sha3.cl' ]));
// fs.writeFileSync('astrobwt_gen.cl', astrobwt);
fs.writeFileSync('astrobwt_cl.h', text2h(astrobwt, 'xmrig', 'astrobwt_cl'));
}
function astrobwt_v2()
{
const astrobwt = opencl_minify(addIncludes('astrobwt_v2.cl', [ 'BWT.cl', 'salsa20.cl', 'sha3.cl' ]));
fs.writeFileSync('astrobwt_v2_cl.h', text2h(astrobwt, 'xmrig', 'astrobwt_v2_cl'));
}
function kawpow()
{
const kawpow = opencl_minify(addIncludes('kawpow.cl', [ 'defs.h' ]));
@ -105,16 +88,6 @@ process.chdir(path.resolve('src/backend/opencl/cl/rx'));
rx();
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/astrobwt'));
astrobwt();
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/astrobwt_v2'));
astrobwt_v2();
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/kawpow'));

View file

@ -1,5 +1,5 @@
Copyright © 2009 CNRS
Copyright © 2009-2021 Inria. All rights reserved.
Copyright © 2009-2022 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,18 @@ bug fixes (and other actions) for each version of hwloc since version
0.9.
Version 2.7.1
-------------
* Workaround crashes when virtual machines report incoherent x86 CPUID
information about numbers of cores and threads.
Thanks to Peter Bense for the report.
* Use setenv() instead of putenv() when trying to force enable oneAPI L0
support, to avoid issues with applications that touch the environment,
thanks to Josh Hursey for the patch.
* Add some warnings at the end of configure when GPU libraries are
missing on the system or their path is missing in the environment.
Version 2.7.0
-------------
* Backends

View file

@ -9,7 +9,7 @@
major=2
minor=7
release=0
release=1
# greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be
@ -22,7 +22,7 @@ greek=
# The date when this release was created
date="Dec 06, 2021"
date="Mar 20, 2022"
# 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,7 @@ snapshot_version=${major}.${minor}.${release}${greek}-git
# 2. Version numbers are described in the Libtool current:revision:age
# format.
libhwloc_so_version=20:2:5
libhwloc_so_version=20:3:5
libnetloc_so_version=0:0:0
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj

View file

@ -29,7 +29,7 @@
* THAT IS IN THE PDF/HTML THAT IS ***NOT*** IN hwloc.h!
*
* There are entire paragraph-length descriptions, discussions, and
* pretty prictures to explain subtle corner cases, provide concrete
* pretty pictures to explain subtle corner cases, provide concrete
* examples, etc.
*
* Please, go read the documentation. :-)
@ -517,7 +517,7 @@ struct hwloc_obj {
* objects).
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these CPUs may not be allowed for binding,
* some of these CPUs may be online but not allowed for binding,
* see hwloc_topology_get_allowed_cpuset().
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
@ -549,7 +549,7 @@ struct hwloc_obj {
* nodes more precisely.
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these nodes may not be allowed for allocation,
* some of these nodes may be online but not allowed for allocation,
* see hwloc_topology_get_allowed_nodeset().
*
* If there are no NUMA nodes in the machine, all the memory is close to this
@ -642,7 +642,7 @@ union hwloc_obj_attr_u {
unsigned char revision;
float linkspeed; /* in GB/s */
} pcidev;
/** \brief Bridge specific Object Attribues */
/** \brief Bridge specific Object Attributes */
struct hwloc_bridge_attr_s {
union {
struct hwloc_pcidev_attr_s pci;
@ -1089,7 +1089,7 @@ HWLOC_DECLSPEC int hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const c
*
* Some operating systems only support binding threads or processes to a single PU.
* Others allow binding to larger sets such as entire Cores or Packages or
* even random sets of invididual PUs. In such operating system, the scheduler
* even random sets of individual PUs. In such operating system, the scheduler
* is free to run the task on one of these PU, then migrate it to another PU, etc.
* It is often useful to call hwloc_bitmap_singlify() on the target CPU set before
* passing it to the binding function to avoid these expensive migrations.
@ -1167,7 +1167,7 @@ typedef enum {
* CPUs are idle, operating systems may execute the thread/process
* on those other CPUs instead of the designated CPUs, to let them
* progress anyway. Strict binding means that the thread/process
* will _never_ execute on other cpus than the designated CPUs, even
* will _never_ execute on other CPUs than the designated CPUs, even
* when those are busy with other tasks and other CPUs are idle.
*
* \note Depending on the operating system, strict binding may not
@ -1204,7 +1204,7 @@ typedef enum {
HWLOC_CPUBIND_NOMEMBIND = (1<<3)
} hwloc_cpubind_flags_t;
/** \brief Bind current process or thread on cpus given in physical bitmap \p set.
/** \brief Bind current process or thread on CPUs given in physical bitmap \p set.
*
* \return -1 with errno set to ENOSYS if the action is not supported
* \return -1 with errno set to EXDEV if the binding cannot be enforced
@ -1219,7 +1219,7 @@ HWLOC_DECLSPEC int hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_cpus
*/
HWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
/** \brief Bind a process \p pid on cpus given in physical bitmap \p set.
/** \brief Bind a process \p pid on CPUs given in physical bitmap \p set.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
@ -1250,7 +1250,7 @@ HWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t
HWLOC_DECLSPEC int hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
#ifdef hwloc_thread_t
/** \brief Bind a thread \p thread on cpus given in physical bitmap \p set.
/** \brief Bind a thread \p thread on CPUs given in physical bitmap \p set.
*
* \note \p hwloc_thread_t is \p pthread_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
@ -1914,8 +1914,9 @@ HWLOC_DECLSPEC int hwloc_topology_set_components(hwloc_topology_t __hwloc_restri
enum hwloc_topology_flags_e {
/** \brief Detect the whole system, ignore reservations, include disallowed objects.
*
* Gather all resources, even if some were disabled by the administrator.
* Gather all online resources, even if some were disabled by the administrator.
* For instance, ignore Linux Cgroup/Cpusets and gather all processors and memory nodes.
* However offline PUs and NUMA nodes are still ignored.
*
* When this flag is not set, PUs and NUMA nodes that are disallowed are not added to the topology.
* Parent objects (package, core, cache, etc.) are added only if some of their children are allowed.
@ -2066,10 +2067,12 @@ enum hwloc_topology_flags_e {
*
* Set a OR'ed set of ::hwloc_topology_flags_e onto a topology that was not yet loaded.
*
* If this function is called multiple times, the last invokation will erase
* If this function is called multiple times, the last invocation will erase
* and replace the set of flags that was previously set.
*
* The flags set in a topology may be retrieved with hwloc_topology_get_flags()
* By default, no flags are set (\c 0).
*
* The flags set in a topology may be retrieved with hwloc_topology_get_flags().
*/
HWLOC_DECLSPEC int hwloc_topology_set_flags (hwloc_topology_t topology, unsigned long flags);
@ -2077,6 +2080,9 @@ HWLOC_DECLSPEC int hwloc_topology_set_flags (hwloc_topology_t topology, unsigned
*
* Get the OR'ed set of ::hwloc_topology_flags_e of a topology.
*
* If hwloc_topology_set_flags() was not called earlier,
* no flags are set (\c 0 is returned).
*
* \return the flags previously set with hwloc_topology_set_flags().
*/
HWLOC_DECLSPEC unsigned long hwloc_topology_get_flags (hwloc_topology_t topology);

View file

@ -11,10 +11,10 @@
#ifndef HWLOC_CONFIG_H
#define HWLOC_CONFIG_H
#define HWLOC_VERSION "2.7.0"
#define HWLOC_VERSION "2.7.1"
#define HWLOC_VERSION_MAJOR 2
#define HWLOC_VERSION_MINOR 7
#define HWLOC_VERSION_RELEASE 0
#define HWLOC_VERSION_RELEASE 1
#define HWLOC_VERSION_GREEK ""
#define __hwloc_restrict

View file

@ -1,5 +1,5 @@
/*
* Copyright © 2019-2020 Inria. All rights reserved.
* Copyright © 2019-2022 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -354,7 +354,7 @@ hwloc_memattr_register(hwloc_topology_t topology,
* \p flags must be \c 0 for now.
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when refering to accesses performed by CPU cores.
* when referring to accesses performed by CPU cores.
* ::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.
@ -398,7 +398,7 @@ hwloc_memattr_set_value(hwloc_topology_t topology,
* values.
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when refering to accesses performed by CPU cores.
* when referring to accesses performed by CPU cores.
* ::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.
@ -408,7 +408,7 @@ hwloc_memattr_get_targets(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
struct hwloc_location *initiator,
unsigned long flags,
unsigned *nrp, hwloc_obj_t *targets, hwloc_uint64_t *values);
unsigned *nr, hwloc_obj_t *targets, hwloc_uint64_t *values);
/** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
*

View file

@ -614,10 +614,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
eax = 0x01;
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
infos->apicid = ebx >> 24;
if (edx & (1 << 28))
if (edx & (1 << 28)) {
legacy_max_log_proc = 1 << hwloc_flsl(((ebx >> 16) & 0xff) - 1);
else
} else {
hwloc_debug("HTT bit not set in CPUID 0x01.edx, assuming legacy_max_log_proc = 1\n");
legacy_max_log_proc = 1;
}
hwloc_debug("APIC ID 0x%02x legacy_max_log_proc %u\n", infos->apicid, legacy_max_log_proc);
infos->ids[PKG] = infos->apicid / legacy_max_log_proc;
legacy_log_proc_id = infos->apicid % legacy_max_log_proc;
@ -680,12 +683,23 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
unsigned max_nbcores;
unsigned max_nbthreads;
unsigned threadid __hwloc_attribute_unused;
hwloc_debug("Trying to get core/thread IDs from 0x04...\n");
max_nbcores = ((eax >> 26) & 0x3f) + 1;
max_nbthreads = legacy_max_log_proc / max_nbcores;
hwloc_debug("thus %u threads\n", max_nbthreads);
threadid = legacy_log_proc_id % max_nbthreads;
infos->ids[CORE] = legacy_log_proc_id / max_nbthreads;
hwloc_debug("this is thread %u of core %u\n", threadid, infos->ids[CORE]);
hwloc_debug("found %u cores max\n", max_nbcores);
/* some VMs (e.g. issue#525) don't report valid information, check things before dividing by 0. */
if (!max_nbcores) {
hwloc_debug("cannot detect core/thread IDs from 0x04 without a valid max of cores\n");
} else {
max_nbthreads = legacy_max_log_proc / max_nbcores;
hwloc_debug("found %u threads max\n", max_nbthreads);
if (!max_nbthreads) {
hwloc_debug("cannot detect core/thread IDs from 0x04 without a valid max of threads\n");
} else {
threadid = legacy_log_proc_id % max_nbthreads;
infos->ids[CORE] = legacy_log_proc_id / max_nbthreads;
hwloc_debug("this is thread %u of core %u\n", threadid, infos->ids[CORE]);
}
}
}
}

View file

@ -3,6 +3,7 @@
* Copyright © 2009-2021 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.
* See COPYING in top-level directory.
*/
@ -52,29 +53,41 @@
#include <windows.h>
#endif
#ifdef HWLOC_HAVE_LEVELZERO
/*
* Define ZES_ENABLE_SYSMAN=1 early so that the LevelZero backend gets Sysman enabled.
*
* Only if the levelzero was enabled in this build so that we don't enable sysman
* for external levelzero users when hwloc doesn't need it. If somebody ever loads
* an external levelzero plugin in a hwloc library built without levelzero (unlikely),
* he may have to manually set ZES_ENABLE_SYSMAN=1.
*
* Use the constructor if supported and/or the Windows DllMain callback.
* Do it in the main hwloc library instead of the levelzero component because
* the latter could be loaded later as a plugin.
*
* L0 seems to be using getenv() to check this variable on Windows
* (at least in the Intel Compute-Runtime of March 2021),
* so use putenv() to set the variable.
* but setenv() doesn't seem to exist on Windows, hence use putenv() to set the variable.
*
* For the record, Get/SetEnvironmentVariable() is not exactly the same as getenv/putenv():
* - getenv() doesn't see what was set with SetEnvironmentVariable()
* - GetEnvironmentVariable() doesn't see putenv() in cygwin (while it does in MSVC and MinGW).
* Hence, if L0 ever switches from getenv() to GetEnvironmentVariable(),
* it will break in cygwin, we'll have to use both putenv() and SetEnvironmentVariable().
* Hopefully L0 will be provide a way to enable Sysman without env vars before it happens.
* Hopefully L0 will provide a way to enable Sysman without env vars before it happens.
*/
#if HWLOC_HAVE_ATTRIBUTE_CONSTRUCTOR
static void hwloc_constructor(void) __attribute__((constructor));
static void hwloc_constructor(void)
{
if (!getenv("ZES_ENABLE_SYSMAN"))
putenv((char *) "ZES_ENABLE_SYSMAN=1");
#ifdef HWLOC_WIN_SYS
putenv("ZES_ENABLE_SYSMAN=1");
#else
setenv("ZES_ENABLE_SYSMAN", "1", 1);
#endif
}
#endif
#ifdef HWLOC_WIN_SYS
@ -82,11 +95,14 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH) {
if (!getenv("ZES_ENABLE_SYSMAN"))
/* Windows does not have a setenv, so use putenv. */
putenv((char *) "ZES_ENABLE_SYSMAN=1");
}
return TRUE;
}
#endif
#endif /* HWLOC_HAVE_LEVELZERO */
unsigned hwloc_get_api_version(void)
{

View file

@ -109,7 +109,7 @@ private:
}
alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N]{};
alignas(8) uint8_t m_blobs[2][Job::kMaxBlobSize * N]{};
Job m_jobs[2];
uint32_t m_rounds[2] = { 0, 0 };
uint64_t m_nonce_mask[2] = { 0, 0 };

View file

@ -436,10 +436,6 @@ rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
out.AddMember("argon2-impl", argon2::Impl::name().toJSON(), allocator);
# endif
# ifdef XMRIG_ALGO_ASTROBWT
out.AddMember("astrobwt-max-size", cpu.astrobwtMaxSize(), allocator);
# endif
out.AddMember("hugepages", d_ptr->hugePages(2, doc), allocator);
out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (d_ptr->ways() * d_ptr->algo.l3()) : 0), allocator);

View file

@ -45,11 +45,6 @@ const char *CpuConfig::kAsm = "asm";
const char *CpuConfig::kArgon2Impl = "argon2-impl";
#endif
#ifdef XMRIG_ALGO_ASTROBWT
const char *CpuConfig::kAstroBWTMaxSize = "astrobwt-max-size";
const char *CpuConfig::kAstroBWTAVX2 = "astrobwt-avx2";
#endif
extern template class Threads<CpuThreads>;
@ -89,11 +84,6 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kArgon2Impl), m_argon2Impl.toJSON(), allocator);
# endif
# ifdef XMRIG_ALGO_ASTROBWT
obj.AddMember(StringRef(kAstroBWTMaxSize), m_astrobwtMaxSize, allocator);
obj.AddMember(StringRef(kAstroBWTAVX2), m_astrobwtAVX2, allocator);
# endif
m_threads.toJSON(obj, doc);
return obj;
@ -158,24 +148,6 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
m_argon2Impl = Json::getString(value, kArgon2Impl);
# endif
# ifdef XMRIG_ALGO_ASTROBWT
const auto& astroBWTMaxSize = Json::getValue(value, kAstroBWTMaxSize);
if (astroBWTMaxSize.IsNull() || !astroBWTMaxSize.IsInt()) {
m_shouldSave = true;
}
else {
m_astrobwtMaxSize = std::min(std::max(astroBWTMaxSize.GetInt(), 400), 1200);
}
const auto& astroBWTAVX2 = Json::getValue(value, kAstroBWTAVX2);
if (astroBWTAVX2.IsNull() || !astroBWTAVX2.IsBool()) {
m_shouldSave = true;
}
else {
m_astrobwtAVX2 = astroBWTAVX2.GetBool();
}
# endif
m_threads.read(value);
generate();
@ -206,7 +178,6 @@ void xmrig::CpuConfig::generate()
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, m_limit);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, m_limit);
count += xmrig::generate<Algorithm::ARGON2>(m_threads, m_limit);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, m_limit);
count += xmrig::generate<Algorithm::GHOSTRIDER>(m_threads, m_limit);
m_shouldSave |= count > 0;

View file

@ -56,11 +56,6 @@ public:
static const char *kArgon2Impl;
# endif
# ifdef XMRIG_ALGO_ASTROBWT
static const char *kAstroBWTMaxSize;
static const char *kAstroBWTAVX2;
# endif
CpuConfig() = default;
bool isHwAES() const;
@ -69,7 +64,6 @@ public:
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
void read(const rapidjson::Value &value);
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePageSize > 0; }
inline bool isHugePagesJit() const { return m_hugePagesJit; }
@ -78,7 +72,6 @@ public:
inline const Assembly &assembly() const { return m_assembly; }
inline const String &argon2Impl() const { return m_argon2Impl; }
inline const Threads<CpuThreads> &threads() const { return m_threads; }
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
inline int priority() const { return m_priority; }
inline size_t hugePageSize() const { return m_hugePageSize * 1024U; }
inline uint32_t limit() const { return m_limit; }
@ -96,12 +89,10 @@ private:
AesMode m_aes = AES_AUTO;
Assembly m_assembly;
bool m_astrobwtAVX2 = false;
bool m_enabled = true;
bool m_hugePagesJit = false;
bool m_shouldSave = false;
bool m_yield = true;
int m_astrobwtMaxSize = 550;
int m_memoryPool = 0;
int m_priority = -1;
size_t m_hugePageSize = kDefaultHugePageSizeKb;

View file

@ -153,22 +153,6 @@ size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t
#endif
#ifdef XMRIG_ALGO_ASTROBWT
template<>
size_t inline generate<Algorithm::ASTROBWT>(Threads<CpuThreads>& threads, uint32_t limit)
{
size_t count = 0;
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
auto v2 = Cpu::info()->threads(Algorithm::ASTROBWT_DERO_2, limit);
count += threads.move(Algorithm::kASTROBWT_DERO_2, std::move(v2));
}
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, limit);
return count;
}
#endif
#ifdef XMRIG_ALGO_GHOSTRIDER
template<>
size_t inline generate<Algorithm::GHOSTRIDER>(Threads<CpuThreads>& threads, uint32_t limit)

View file

@ -35,11 +35,9 @@
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, size_t threads, const std::vector<int64_t>& affinities) :
algorithm(algorithm),
assembly(config.assembly()),
astrobwtAVX2(config.astrobwtAVX2()),
hugePages(config.isHugePages()),
hwAES(config.isHwAES()),
yield(config.isYield()),
astrobwtMaxSize(config.astrobwtMaxSize()),
priority(config.priority()),
affinity(thread.affinity()),
miner(miner),

View file

@ -58,11 +58,9 @@ public:
const Algorithm algorithm;
const Assembly assembly;
const bool astrobwtAVX2;
const bool hugePages;
const bool hwAES;
const bool yield;
const int astrobwtMaxSize;
const int priority;
const int64_t affinity;
const Miner *miner;

View file

@ -44,11 +44,6 @@
#endif
#ifdef XMRIG_ALGO_ASTROBWT
# include "crypto/astrobwt/AstroBWT.h"
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "backend/common/benchmark/BenchState.h"
#endif
@ -73,11 +68,9 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
Worker(id, data.affinity, data.priority),
m_algorithm(data.algorithm),
m_assembly(data.assembly),
m_astrobwtAVX2(data.astrobwtAVX2),
m_hwAES(data.hwAES),
m_yield(data.yield),
m_av(data.av()),
m_astrobwtMaxSize(data.astrobwtMaxSize * 1000),
m_miner(data.miner),
m_threads(data.threads),
m_ctx()
@ -223,11 +216,6 @@ bool xmrig::CpuWorker<N>::selfTest()
}
# endif
# ifdef XMRIG_ALGO_ASTROBWT
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO) return verify(Algorithm::ASTROBWT_DERO, astrobwt_dero_test_out);
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO_2) return verify(Algorithm::ASTROBWT_DERO_2, astrobwt_dero_2_test_out);
# endif
return false;
}
@ -317,21 +305,6 @@ void xmrig::CpuWorker<N>::start()
{
switch (job.algorithm().family()) {
# ifdef XMRIG_ALGO_ASTROBWT
case Algorithm::ASTROBWT:
if (job.algorithm().id() == Algorithm::ASTROBWT_DERO) {
if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize, m_astrobwtAVX2)) {
valid = false;
}
}
else {
if (!astrobwt::astrobwt_dero_v2(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash)) {
valid = false;
}
}
break;
# endif
# ifdef XMRIG_ALGO_GHOSTRIDER
case Algorithm::GHOSTRIDER:
if (N == 8) {

View file

@ -83,14 +83,12 @@ private:
void allocateCnCtx();
void consumeJob();
alignas(16) uint8_t m_hash[N * 32]{ 0 };
alignas(8) uint8_t m_hash[N * 32]{ 0 };
const Algorithm m_algorithm;
const Assembly m_assembly;
const bool m_astrobwtAVX2;
const bool m_hwAES;
const bool m_yield;
const CnHash::AlgoVariant m_av;
const int m_astrobwtMaxSize;
const Miner *m_miner;
const size_t m_threads;
cryptonight_ctx *m_ctx[N];

View file

@ -362,16 +362,6 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3
}
# endif
# ifdef XMRIG_ALGO_ASTROBWT
if (f == Algorithm::ASTROBWT) {
CpuThreads threads;
for (size_t i = 0; i < count; ++i) {
threads.add(i, 0);
}
return threads;
}
# endif
# ifdef XMRIG_ALGO_GHOSTRIDER
if (f == Algorithm::GHOSTRIDER) {
return CpuThreads(std::max<size_t>(count / 2, 1), 8);

View file

@ -318,13 +318,6 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
size_t scratchpad = algorithm.l3();
uint32_t intensity = algorithm.maxIntensity() == 1 ? 0 : 1;
# ifdef XMRIG_ALGO_ASTROBWT
if (algorithm == Algorithm::ASTROBWT_DERO) {
// Use fake low value to force usage of all available cores for AstroBWT (taking 'limit' into account)
scratchpad = 16 * 1024;
}
# endif
if (cache->attr->cache.depth == 3) {
for (size_t i = 0; i < cache->arity; ++i) {
hwloc_obj_t l2 = cache->children[i];

View file

@ -40,11 +40,6 @@
#include "core/Controller.h"
#ifdef XMRIG_ALGO_ASTROBWT
# include "backend/cuda/runners/CudaAstroBWTRunner.h"
#endif
#ifdef XMRIG_ALGO_KAWPOW
# include "crypto/kawpow/KPCache.h"
# include "crypto/kawpow/KPHash.h"
@ -220,12 +215,6 @@ public:
size_t algo_l3 = algo.l3();
# ifdef XMRIG_ALGO_ASTROBWT
if (algo.id() == Algorithm::ASTROBWT_DERO) {
algo_l3 = CudaAstroBWTRunner::BWT_DATA_STRIDE * 17 + 1024;
}
# endif
size_t i = 0;
for (const auto &data : threads) {
size_t mem_used = (data.thread.threads() * data.thread.blocks()) * algo_l3 / oneMiB;

View file

@ -174,7 +174,6 @@ void xmrig::CudaConfig::generate()
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, devices);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, devices);
count += xmrig::generate<Algorithm::KAWPOW>(m_threads, devices);
generated = true;

View file

@ -135,22 +135,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const
#endif
#ifdef XMRIG_ALGO_ASTROBWT
template<>
size_t inline generate<Algorithm::ASTROBWT>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)
{
size_t count = 0;
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
count += threads.move(Algorithm::kASTROBWT_DERO_2, CudaThreads(devices, Algorithm::ASTROBWT_DERO_2));
}
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
return count;
}
#endif
#ifdef XMRIG_ALGO_KAWPOW
template<>
size_t inline generate<Algorithm::KAWPOW>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)

View file

@ -34,11 +34,6 @@
#endif
#ifdef XMRIG_ALGO_ASTROBWT
# include "backend/cuda/runners/CudaAstroBWTRunner.h"
#endif
#ifdef XMRIG_ALGO_KAWPOW
# include "backend/cuda/runners/CudaKawPowRunner.h"
#endif
@ -76,12 +71,6 @@ xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) :
case Algorithm::ARGON2:
break;
case Algorithm::ASTROBWT:
# ifdef XMRIG_ALGO_ASTROBWT
m_runner = new CudaAstroBWTRunner(id, data);
# endif
break;
case Algorithm::KAWPOW:
# ifdef XMRIG_ALGO_KAWPOW
m_runner = new CudaKawPowRunner(id, data);

View file

@ -54,11 +54,6 @@ if (WITH_CUDA)
list(APPEND SOURCES_BACKEND_CUDA src/backend/cuda/runners/CudaRxRunner.cpp)
endif()
if (WITH_ASTROBWT)
list(APPEND HEADERS_BACKEND_CUDA src/backend/cuda/runners/CudaAstroBWTRunner.h)
list(APPEND SOURCES_BACKEND_CUDA src/backend/cuda/runners/CudaAstroBWTRunner.cpp)
endif()
if (WITH_KAWPOW)
list(APPEND HEADERS_BACKEND_CUDA src/backend/cuda/runners/CudaKawPowRunner.h)
list(APPEND SOURCES_BACKEND_CUDA src/backend/cuda/runners/CudaKawPowRunner.cpp)

View file

@ -1,85 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/cuda/runners/CudaAstroBWTRunner.h"
#include "backend/cuda/CudaLaunchData.h"
#include "backend/cuda/wrappers/CudaLib.h"
#include "base/net/stratum/Job.h"
constexpr uint32_t xmrig::CudaAstroBWTRunner::BWT_DATA_STRIDE;
xmrig::CudaAstroBWTRunner::CudaAstroBWTRunner(size_t index, const CudaLaunchData &data)
: CudaBaseRunner(index, data)
, m_algorithm(data.algorithm)
{
m_intensity = m_data.thread.threads() * m_data.thread.blocks();
m_intensity -= m_intensity % 32;
// Dero HE has very fast blocks, so we can't use high intensity
if ((m_algorithm == Algorithm::ASTROBWT_DERO_2) && (m_intensity > 4096)) {
m_intensity = 4096;
}
}
bool xmrig::CudaAstroBWTRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce)
{
return callWrapper(CudaLib::astroBWTHash(m_ctx, startNonce, m_target, rescount, resnonce));
}
bool xmrig::CudaAstroBWTRunner::set(const Job &job, uint8_t *blob)
{
if (!CudaBaseRunner::set(job, blob)) {
return false;
}
return callWrapper(CudaLib::astroBWTPrepare(m_ctx, static_cast<uint32_t>(m_intensity)));
}
size_t xmrig::CudaAstroBWTRunner::roundSize() const
{
if (m_algorithm == Algorithm::ASTROBWT_DERO_2) {
return m_intensity;
}
constexpr uint32_t STAGE1_SIZE = 147253;
constexpr uint32_t STAGE1_DATA_STRIDE = (STAGE1_SIZE + 256 + 255) & ~255U;
const uint32_t BATCH2_SIZE = static_cast<uint32_t>(m_intensity);
const uint32_t BWT_ALLOCATION_SIZE = BATCH2_SIZE * BWT_DATA_STRIDE;
const uint32_t BATCH1_SIZE = (BWT_ALLOCATION_SIZE / STAGE1_DATA_STRIDE) & ~255U;
return BATCH1_SIZE;
}
size_t xmrig::CudaAstroBWTRunner::processedHashes() const
{
return CudaLib::deviceInt(m_ctx, CudaLib::DeviceAstroBWTProcessedHashes);
}

View file

@ -1,61 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CUDAASTROBWTRUNNER_H
#define XMRIG_CUDAASTROBWTRUNNER_H
#include "backend/cuda/runners/CudaBaseRunner.h"
#include "base/crypto/Algorithm.h"
namespace xmrig {
class CudaAstroBWTRunner : public CudaBaseRunner
{
public:
static constexpr uint32_t BWT_DATA_MAX_SIZE = 560 * 1024 - 256;
static constexpr uint32_t BWT_DATA_STRIDE = (BWT_DATA_MAX_SIZE + 256 + 255) & ~255U;
CudaAstroBWTRunner(size_t index, const CudaLaunchData &data);
protected:
inline size_t intensity() const override { return m_intensity; }
inline size_t roundSize() const override;
inline size_t processedHashes() const override;
bool run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) override;
bool set(const Job &job, uint8_t *blob) override;
private:
size_t m_intensity = 0;
Algorithm m_algorithm;
};
} /* namespace xmrig */
#endif // XMRIG_CUDAASTROBWTRUNNER_H

View file

@ -50,8 +50,6 @@ static String defaultLoader = "libxmrig-cuda.so";
static const char *kAlloc = "alloc";
static const char *kAstroBWTHash = "astroBWTHash";
static const char *kAstroBWTPrepare = "astroBWTPrepare";
static const char *kCnHash = "cnHash";
static const char *kDeviceCount = "deviceCount";
static const char *kDeviceInfo = "deviceInfo";
@ -76,8 +74,6 @@ static const char *kVersion = "version";
using alloc_t = nvid_ctx * (*)(uint32_t, int32_t, int32_t);
using astroBWTHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint32_t *, uint32_t *);
using astroBWTPrepare_t = bool (*)(nvid_ctx *, uint32_t);
using cnHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint64_t, uint32_t *, uint32_t *);
using deviceCount_t = uint32_t (*)();
using deviceInfo_t = bool (*)(nvid_ctx *, int32_t, int32_t, uint32_t, int32_t);
@ -102,8 +98,6 @@ using version_t = uint32_t (*)(Version);
static alloc_t pAlloc = nullptr;
static astroBWTHash_t pAstroBWTHash = nullptr;
static astroBWTPrepare_t pAstroBWTPrepare = nullptr;
static cnHash_t pCnHash = nullptr;
static deviceCount_t pDeviceCount = nullptr;
static deviceInfo_t pDeviceInfo = nullptr;
@ -176,18 +170,6 @@ void xmrig::CudaLib::close()
}
bool xmrig::CudaLib::astroBWTHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept
{
return pAstroBWTHash(ctx, startNonce, target, rescount, resnonce);
}
bool xmrig::CudaLib::astroBWTPrepare(nvid_ctx *ctx, uint32_t batchSize) noexcept
{
return pAstroBWTPrepare(ctx, batchSize);
}
bool xmrig::CudaLib::cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce)
{
return pCnHash(ctx, startNonce, height, target, rescount, resnonce);
@ -410,8 +392,6 @@ void xmrig::CudaLib::load()
DLSYM(Release);
DLSYM(RxHash);
DLSYM(RxPrepare);
DLSYM(AstroBWTHash);
DLSYM(AstroBWTPrepare);
DLSYM(KawPowHash);
DLSYM(KawPowPrepare_v2);
DLSYM(KawPowStopHash);

View file

@ -56,7 +56,6 @@ public:
DevicePciDeviceID,
DevicePciDomainID,
DeviceDatasetHost,
DeviceAstroBWTProcessedHashes,
};
static bool init(const char *fileName = nullptr);
@ -67,8 +66,6 @@ public:
static inline bool isReady() noexcept { return m_ready; }
static inline const String &loader() { return m_loader; }
static bool astroBWTHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept;
static bool astroBWTPrepare(nvid_ctx *ctx, uint32_t batchSize) noexcept;
static bool cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce);
static bool deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm, int32_t dataset_host = -1) noexcept;
static bool deviceInit(nvid_ctx *ctx) noexcept;

View file

@ -29,7 +29,6 @@
#include "backend/opencl/OclConfig.h"
#include "backend/opencl/OclLaunchData.h"
#include "backend/opencl/OclWorker.h"
#include "backend/opencl/runners/OclAstroBWTRunner.h"
#include "backend/opencl/runners/tools/OclSharedState.h"
#include "backend/opencl/wrappers/OclContext.h"
#include "backend/opencl/wrappers/OclLib.h"
@ -204,12 +203,6 @@ public:
size_t algo_l3 = algo.l3();
# ifdef XMRIG_ALGO_ASTROBWT
if (algo.id() == Algorithm::ASTROBWT_DERO) {
algo_l3 = OclAstroBWTRunner::BWT_DATA_STRIDE * 17 + 324;
}
# endif
size_t i = 0;
for (const auto &data : threads) {
size_t mem_used = data.thread.intensity() * algo_l3 / oneMiB;

View file

@ -214,7 +214,6 @@ void xmrig::OclConfig::generate()
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
count += xmrig::generate<Algorithm::CN_FEMTO>(m_threads, devices);
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
count += xmrig::generate<Algorithm::ASTROBWT>(m_threads, devices);
count += xmrig::generate<Algorithm::KAWPOW>(m_threads, devices);
m_shouldSave = count > 0;

View file

@ -129,22 +129,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const
#endif
#ifdef XMRIG_ALGO_ASTROBWT
template<>
size_t inline generate<Algorithm::ASTROBWT>(Threads<OclThreads>& threads, const std::vector<OclDevice>& devices)
{
size_t count = 0;
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
count += threads.move(Algorithm::kASTROBWT_DERO_2, OclThreads(devices, Algorithm::ASTROBWT_DERO_2));
}
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
return count;
}
#endif
#ifdef XMRIG_ALGO_KAWPOW
template<>
size_t inline generate<Algorithm::KAWPOW>(Threads<OclThreads>& threads, const std::vector<OclDevice>& devices)

View file

@ -116,9 +116,7 @@ rapidjson::Value xmrig::OclThread::toJSON(rapidjson::Document &doc) const
out.AddMember(StringRef(kIndex), index(), allocator);
out.AddMember(StringRef(kIntensity), intensity(), allocator);
if (!m_fields.test(ASTROBWT_FIELDS)) {
out.AddMember(StringRef(kWorksize), worksize(), allocator);
}
out.AddMember(StringRef(kWorksize), worksize(), allocator);
if (m_fields.test(STRIDED_INDEX_FIELD)) {
Value si(kArrayType);
@ -144,7 +142,7 @@ rapidjson::Value xmrig::OclThread::toJSON(rapidjson::Document &doc) const
out.AddMember(StringRef(kDatasetHost), isDatasetHost(), allocator);
# endif
}
else if (!m_fields.test(ASTROBWT_FIELDS) && !m_fields.test(KAWPOW_FIELDS)) {
else if (!m_fields.test(KAWPOW_FIELDS)) {
out.AddMember(StringRef(kUnroll), unrollFactor(), allocator);
}

View file

@ -61,20 +61,6 @@ public:
}
# endif
# ifdef XMRIG_ALGO_ASTROBWT
OclThread(uint32_t index, uint32_t intensity, uint32_t threads) :
m_fields(4),
m_threads(threads, -1),
m_index(index),
m_memChunk(0),
m_stridedIndex(0),
m_unrollFactor(1),
m_worksize(1)
{
setIntensity(intensity);
}
# endif
# ifdef XMRIG_ALGO_KAWPOW
OclThread(uint32_t index, uint32_t intensity, uint32_t worksize, uint32_t threads) :
m_fields(8),
@ -113,7 +99,6 @@ private:
enum Fields {
STRIDED_INDEX_FIELD,
RANDOMX_FIELDS,
ASTROBWT_FIELDS,
KAWPOW_FIELDS,
FIELD_MAX
};

View file

@ -35,11 +35,6 @@
# include "backend/opencl/runners/OclRxVmRunner.h"
#endif
#ifdef XMRIG_ALGO_ASTROBWT
# include "backend/opencl/runners/OclAstroBWTRunner.h"
# include "backend/opencl/runners/OclAstroBWT_v2_Runner.h"
#endif
#ifdef XMRIG_ALGO_KAWPOW
# include "backend/opencl/runners/OclKawPowRunner.h"
#endif
@ -91,17 +86,6 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
# endif
break;
case Algorithm::ASTROBWT:
# ifdef XMRIG_ALGO_ASTROBWT
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO_2) {
m_runner = new OclAstroBWT_v2_Runner(id, data);
}
else {
m_runner = new OclAstroBWTRunner(id, data);
}
# endif
break;
case Algorithm::KAWPOW:
# ifdef XMRIG_ALGO_KAWPOW
m_runner = new OclKawPowRunner(id, data);

View file

@ -32,11 +32,6 @@
# include "backend/opencl/cl/rx/randomx_cl.h"
#endif
#ifdef XMRIG_ALGO_ASTROBWT
# include "backend/opencl/cl/astrobwt/astrobwt_cl.h"
# include "backend/opencl/cl/astrobwt_v2/astrobwt_v2_cl.h"
#endif
#ifdef XMRIG_ALGO_KAWPOW
# include "backend/opencl/cl/kawpow/kawpow_cl.h"
# include "backend/opencl/cl/kawpow/kawpow_dag_cl.h"
@ -51,12 +46,6 @@ const char *xmrig::OclSource::get(const Algorithm &algorithm)
}
# endif
# ifdef XMRIG_ALGO_ASTROBWT
if (algorithm.family() == Algorithm::ASTROBWT) {
return (algorithm.id() == Algorithm::ASTROBWT_DERO_2) ? astrobwt_v2_cl : astrobwt_cl;
}
# endif
# ifdef XMRIG_ALGO_KAWPOW
if (algorithm.family() == Algorithm::KAWPOW) {
return kawpow_dag_cl;

View file

@ -1,206 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define STAGE1_SIZE 147253
#define COUNTING_SORT_BITS 11
#define COUNTING_SORT_SIZE (1 << COUNTING_SORT_BITS)
__attribute__((reqd_work_group_size(BWT_GROUP_SIZE, 1, 1)))
__kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32_t data_stride, __global uint64_t* indices, __global uint64_t* tmp_indices)
{
const uint32_t tid = get_local_id(0);
const uint32_t gid = get_group_id(0);
__local int counters[COUNTING_SORT_SIZE][2];
for (uint32_t i = tid; i < COUNTING_SORT_SIZE * 2; i += BWT_GROUP_SIZE)
((__local int*)counters)[i] = 0;
barrier(CLK_LOCAL_MEM_FENCE);
const uint64_t data_offset = (uint64_t)(gid) * data_stride;
__global uint8_t* input = datas + data_offset + 128;
const uint32_t N = data_sizes[gid] + 1;
__global uint64_t* p = (__global uint64_t*)(input);
volatile __local uint8_t* counters_atomic = (volatile __local uint8_t*)(counters);
indices += data_offset;
tmp_indices += data_offset;
for (uint32_t i = tid; i < N; i += BWT_GROUP_SIZE)
{
const uint32_t index = i >> 3;
const uint32_t bit_offset = (i & 7) << 3;
const uint64_t a = p[index];
uint64_t b = p[index + 1];
if (bit_offset == 0)
b = 0;
uint64_t value = (a >> bit_offset) | (b << (64 - bit_offset));
uint2 tmp;
const uchar4 mask = (uchar4)(3, 2, 1, 0);
tmp.x = as_uint(shuffle(as_uchar4(as_uint2(value).y), mask));
tmp.y = as_uint(shuffle(as_uchar4(as_uint2(value).x), mask));
value = as_ulong(tmp);
indices[i] = (value & ((uint64_t)(-1) << 21)) | i;
atomic_add((volatile __local int*)(counters_atomic + (((value >> (64 - COUNTING_SORT_BITS * 2)) & (COUNTING_SORT_SIZE - 1)) << 3)), 1);
atomic_add((volatile __local int*)(counters_atomic + ((value >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
}
barrier(CLK_LOCAL_MEM_FENCE);
if (tid == 0)
{
int t0 = counters[0][0];
int t1 = counters[0][1];
counters[0][0] = t0 - 1;
counters[0][1] = t1 - 1;
for (uint32_t i = 1; i < COUNTING_SORT_SIZE; ++i)
{
t0 += counters[i][0];
t1 += counters[i][1];
counters[i][0] = t0 - 1;
counters[i][1] = t1 - 1;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
for (int i = tid; i < N; i += BWT_GROUP_SIZE)
{
const uint64_t data = indices[i];
const int k = atomic_sub((volatile __local int*)(counters_atomic + (((data >> (64 - COUNTING_SORT_BITS * 2)) & (COUNTING_SORT_SIZE - 1)) << 3)), 1);
tmp_indices[k] = data;
}
barrier(CLK_GLOBAL_MEM_FENCE);
if (tid == 0)
{
for (int i = N - 1; i >= 0; --i)
{
const uint64_t data = tmp_indices[i];
const int k = atomic_sub((volatile __local int*)(counters_atomic + ((data >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
indices[k] = data;
}
}
barrier(CLK_GLOBAL_MEM_FENCE);
const uint32_t N1 = N - 1;
__global uint32_t* indices32 = (__global uint32_t*)(indices);
for (uint32_t i = tid; i < N1; i += BWT_GROUP_SIZE)
{
const uint32_t value = indices32[i * 2 + 1] >> (32 - COUNTING_SORT_BITS * 2);
if (value != (indices32[i * 2 + 3] >> (32 - COUNTING_SORT_BITS * 2)))
continue;
if ((i > 0) && ((indices32[i * 2 - 1] >> (32 - COUNTING_SORT_BITS * 2)) == value))
continue;
uint32_t i1 = i + 2;
while ((i1 < N) && ((indices32[i1 * 2 + 1] >> (32 - COUNTING_SORT_BITS * 2)) == value))
++i1;
for (uint32_t j = i; j < i1; ++j)
{
uint64_t t = indices[j];
for (uint32_t k = j + 1; k < i1; ++k)
{
if (t > indices[k])
{
const uint64_t t1 = t;
t = indices[k];
indices[k] = t1;
}
}
indices[j] = t;
}
}
barrier(CLK_GLOBAL_MEM_FENCE);
--input;
__global uint8_t* output = (__global uint8_t*)(tmp_indices);
for (int i = tid; i <= N; i += BWT_GROUP_SIZE)
output[i] = input[indices[i] & ((1 << 21) - 1)];
}
__kernel void filter(uint32_t nonce, uint32_t bwt_max_size, __global const uint32_t* hashes, __global uint32_t* filtered_hashes)
{
const uint32_t global_id = get_global_id(0);
__global const uint32_t* hash = hashes + global_id * (32 / sizeof(uint32_t));
const uint32_t stage2_size = STAGE1_SIZE + (*hash & 0xfffff);
if (stage2_size < bwt_max_size)
{
const int index = atomic_add((volatile __global int*)(filtered_hashes), 1) * (36 / sizeof(uint32_t)) + 1;
filtered_hashes[index] = nonce + global_id;
#pragma unroll 8
for (uint32_t i = 0; i < 8; ++i)
filtered_hashes[index + i + 1] = hash[i];
}
}
__kernel void prepare_batch2(__global uint32_t* hashes, __global uint32_t* filtered_hashes, __global uint32_t* data_sizes)
{
const uint32_t global_id = get_global_id(0);
const uint32_t N = filtered_hashes[0] - get_global_size(0);
if (global_id == 0)
filtered_hashes[0] = N;
__global uint32_t* hash = hashes + global_id * 8;
__global uint32_t* filtered_hash = filtered_hashes + (global_id + N) * 9 + 1;
const uint32_t stage2_size = STAGE1_SIZE + (filtered_hash[1] & 0xfffff);
data_sizes[global_id] = stage2_size;
#pragma unroll 8
for (uint32_t i = 0; i < 8; ++i)
hash[i] = filtered_hash[i + 1];
}
__kernel void find_shares(__global const uint64_t* hashes, __global const uint32_t* filtered_hashes, uint64_t target, __global uint32_t* shares)
{
const uint32_t global_index = get_global_id(0);
if (hashes[global_index * 4 + 3] < target)
{
const uint32_t idx = atomic_inc(shares + 0xFF);
if (idx < 0xFF)
shares[idx] = filtered_hashes[(filtered_hashes[0] + global_index) * 9 + 1];
}
}

View file

@ -1,35 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
typedef uchar uint8_t;
typedef ushort uint16_t;
typedef uint uint32_t;
typedef ulong uint64_t;
typedef int int32_t;
typedef long int64_t;
#include "BWT.cl"
#include "salsa20.cl"
#include "sha3.cl"

View file

@ -1,399 +0,0 @@
#pragma once
namespace xmrig {
static const char astrobwt_cl[12489] = {
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,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x34,
0x37,0x32,0x35,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x20,
0x31,0x31,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x31,
0x20,0x3c,0x3c,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,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,0x42,0x57,0x54,0x5f,
0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,
0x42,0x57,0x54,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x2c,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
0x2a,0x20,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x74,0x6d,0x70,
0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,
0x65,0x74,0x5f,0x6c,0x6f,0x63,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,0x67,
0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,
0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x5b,0x32,0x5d,0x3b,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,
0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x32,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,
0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x5b,0x69,0x5d,0x3d,0x30,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,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
0x5f,0x74,0x29,0x28,0x67,0x69,0x64,0x29,0x2a,0x64,0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x64,0x61,0x74,0x61,0x73,0x2b,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,
0x31,0x32,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x3d,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,
0x5b,0x67,0x69,0x64,0x5d,0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0x0a,0x76,0x6f,0x6c,0x61,0x74,
0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,
0x6f,0x6d,0x69,0x63,0x3d,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,
0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,
0x3b,0x0a,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,
0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,
0x69,0x3e,0x3e,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,
0x28,0x69,0x26,0x37,0x29,0x3c,0x3c,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x3d,0x70,0x5b,0x69,0x6e,0x64,
0x65,0x78,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x62,0x3d,0x70,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x62,
0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x3d,0x30,0x29,0x0a,0x62,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,
0x65,0x3d,0x28,0x61,0x3e,0x3e,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x7c,0x28,0x62,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x62,0x69,0x74,0x5f,0x6f,0x66,
0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x6d,0x70,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x34,0x20,
0x6d,0x61,0x73,0x6b,0x3d,0x28,0x75,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x33,0x2c,0x32,0x2c,0x31,0x2c,0x30,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x78,0x3d,0x61,0x73,
0x5f,0x75,0x69,0x6e,0x74,0x28,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,
0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2e,0x79,0x29,0x2c,0x6d,0x61,0x73,0x6b,0x29,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x79,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,
0x28,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x76,0x61,0x6c,0x75,
0x65,0x29,0x2e,0x78,0x29,0x2c,0x6d,0x61,0x73,0x6b,0x29,0x29,0x3b,0x0a,0x76,0x61,0x6c,0x75,0x65,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x74,0x6d,0x70,
0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3d,0x28,0x76,0x61,0x6c,0x75,0x65,0x26,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,
0x28,0x2d,0x31,0x29,0x3c,0x3c,0x32,0x31,0x29,0x29,0x7c,0x69,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,
0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,
0x2b,0x28,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,
0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,
0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x76,0x61,0x6c,0x75,
0x65,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x29,0x3c,0x3c,0x33,0x29,0x2b,
0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x7d,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,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x30,0x3d,0x63,0x6f,0x75,0x6e,0x74,
0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x31,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x31,0x5d,
0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,
0x30,0x5d,0x5b,0x31,0x5d,0x3d,0x74,0x31,0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,
0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x30,0x2b,0x3d,
0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x31,0x2b,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,
0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,
0x73,0x5b,0x69,0x5d,0x5b,0x31,0x5d,0x3d,0x74,0x31,0x2d,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,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,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,
0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,
0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x28,0x64,0x61,0x74,0x61,
0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,
0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x6d,
0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,
0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x4e,0x2d,0x31,0x3b,0x20,0x69,0x3e,0x3d,0x30,0x3b,0x20,0x2d,0x2d,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,
0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,
0x2b,0x28,0x28,0x64,0x61,0x74,0x61,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,
0x29,0x3c,0x3c,0x33,0x29,0x2b,0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,
0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,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,0x4e,0x31,0x3d,0x4e,0x2d,0x31,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,
0x33,0x32,0x5b,0x69,0x2a,0x32,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,
0x53,0x2a,0x32,0x29,0x3b,0x0a,0x69,0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x21,0x3d,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x5b,0x69,0x2a,0x32,0x2b,0x33,
0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x29,0x0a,0x63,
0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x69,0x66,0x28,0x28,0x69,0x3e,0x30,0x29,0x26,0x26,0x28,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x5b,0x69,
0x2a,0x32,0x2d,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,
0x29,0x3d,0x3d,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x31,
0x3d,0x69,0x2b,0x32,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x69,0x31,0x3c,0x4e,0x29,0x26,0x26,0x28,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,
0x5b,0x69,0x31,0x2a,0x32,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,
0x2a,0x32,0x29,0x29,0x3d,0x3d,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x0a,0x2b,0x2b,0x69,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x3d,0x69,0x3b,0x20,0x6a,0x3c,0x69,0x31,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x3d,0x69,
0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6a,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x6a,0x2b,0x31,0x3b,0x20,
0x6b,0x3c,0x69,0x31,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x29,0x0a,0x7b,0x0a,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x31,0x3d,0x74,0x3b,0x0a,0x74,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,
0x5d,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x74,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6a,0x5d,
0x3d,0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,
0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x2d,0x2d,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,
0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x74,0x6d,0x70,
0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x3d,0x4e,0x3b,
0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x69,0x5d,0x3d,0x69,0x6e,
0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x26,0x28,0x28,0x31,0x3c,0x3c,0x32,0x31,0x29,0x2d,0x31,0x29,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,
0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,
0x63,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x77,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,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,0x64,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,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,
0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x28,0x2a,0x68,0x61,0x73,0x68,0x26,0x30,0x78,
0x66,0x66,0x66,0x66,0x66,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3c,0x62,0x77,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x73,
0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,
0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x66,0x69,0x6c,0x74,0x65,
0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x2c,0x31,0x29,0x2a,0x28,0x33,0x36,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x29,0x29,0x2b,0x31,0x3b,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x6e,
0x6f,0x6e,0x63,0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x66,0x69,
0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x69,0x2b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,
0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x70,0x61,0x72,0x65,0x5f,0x62,0x61,0x74,0x63,
0x68,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,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,0x64,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,0x4e,0x3d,0x66,0x69,0x6c,
0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,
0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,
0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x3d,0x4e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,
0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,
0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2b,0x4e,0x29,0x2a,0x39,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,
0x45,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x26,0x30,0x78,0x66,0x66,0x66,0x66,0x66,0x29,0x3b,0x0a,0x64,0x61,
0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x5d,0x3d,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3b,
0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,
0x68,0x61,0x73,0x68,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,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,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,
0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x72,0x67,0x65,0x74,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,0x0a,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,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,
0x61,0x73,0x68,0x65,0x73,0x5b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,
0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x2a,0x39,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x54,0x41,0x54,0x45,
0x28,0x76,0x2c,0x63,0x29,0x20,0x28,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x76,0x2c,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x63,0x29,0x29,0x0a,0x23,0x64,
0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4f,0x52,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x5e,0x20,0x28,0x77,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,
0x6e,0x65,0x20,0x50,0x4c,0x55,0x53,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x2b,0x20,0x28,0x77,0x29,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,0x53,0x41,0x4c,
0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,
0x76,0x6f,0x69,0x64,0x20,0x53,0x61,0x6c,0x73,0x61,0x32,0x30,0x5f,0x58,0x4f,0x52,0x4b,0x65,0x79,0x53,0x74,0x72,0x65,0x61,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,
0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,
0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,
0x74,0x5f,0x6c,0x6f,0x63,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,0x67,0x3d,
0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x6f,0x75,0x74,0x70,0x75,
0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2b,0x31,0x32,0x38,0x3b,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2d,0x31,0x32,0x38,
0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x69,0x3d,0x74,0x3b,0x20,0x69,0x3c,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x20,0x69,
0x2b,0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x70,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x3d,0x6b,0x65,0x79,0x73,0x2b,
0x67,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x6f,
0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x74,0x2a,0x36,0x34,0x29,0x29,0x2f,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,0x6f,
0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x3d,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x6a,0x32,0x3d,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x33,0x3d,0x6b,0x5b,
0x32,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x34,0x3d,0x6b,0x5b,0x33,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x31,0x3d,0x6b,0x5b,0x34,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x6a,0x31,0x32,0x3d,0x6b,0x5b,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x33,
0x3d,0x6b,0x5b,0x36,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x34,0x3d,0x6b,0x5b,0x37,0x5d,0x3b,0x0a,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x30,0x3d,0x30,0x78,0x36,0x31,0x37,0x30,0x37,0x38,0x36,0x35,0x55,0x3b,0x0a,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x35,0x3d,0x30,0x78,0x33,0x33,0x32,0x30,0x36,0x34,0x36,0x45,0x55,0x3b,0x0a,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x30,0x3d,0x30,0x78,0x37,0x39,0x36,0x32,0x32,0x44,0x33,0x32,0x55,0x3b,0x0a,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x35,0x3d,0x30,0x78,0x36,0x42,0x32,0x30,0x36,0x35,0x37,0x34,0x55,0x3b,0x0a,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x36,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x37,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x39,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x69,0x3d,0x74,0x2a,0x36,0x34,0x3b,0x20,0x69,0x3c,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,
0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x38,0x5f,0x31,0x3d,0x6a,0x38,0x2b,0x28,0x69,0x2f,0x36,0x34,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x30,0x3d,0x6a,0x30,
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x3d,0x6a,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x32,0x3d,0x6a,0x32,
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x33,0x3d,0x6a,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x34,0x3d,0x6a,0x34,
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x35,0x3d,0x6a,0x35,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x36,0x3d,0x6a,0x36,
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x37,0x3d,0x6a,0x37,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x38,0x3d,0x6a,0x38,
0x5f,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x39,0x3d,0x6a,0x39,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x30,
0x3d,0x6a,0x31,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x31,0x3d,0x6a,0x31,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x78,0x31,0x32,0x3d,0x6a,0x31,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x33,0x3d,0x6a,0x31,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x34,0x3d,0x6a,0x31,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x35,0x3d,0x6a,0x31,0x35,0x3b,0x0a,
0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x35,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,
0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x31,0x32,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,
0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,
0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,
0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x78,0x38,0x29,0x2c,0x31,
0x38,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,
0x78,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
0x28,0x20,0x78,0x39,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,
0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x39,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,
0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x36,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,
0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,
0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,
0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
0x28,0x20,0x78,0x36,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,
0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x37,0x2c,0x52,
0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,
0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x33,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,
0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x37,0x29,0x2c,0x31,
0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,
0x78,0x33,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,
0x20,0x78,0x31,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,
0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,
0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,
0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,
0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,
0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x36,0x29,0x2c,0x31,0x33,
0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,
0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
0x28,0x78,0x31,0x30,0x2c,0x78,0x39,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,
0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x31,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,
0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x38,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,
0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x34,0x29,0x2c,
0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,
0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x31,0x32,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x6f,0x75,0x74,0x70,0x75,
0x74,0x5b,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x30,0x2c,0x6a,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,
0x28,0x78,0x31,0x2c,0x6a,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x32,0x2c,0x6a,0x32,0x29,0x3b,0x0a,
0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x33,0x2c,0x6a,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x34,0x5d,
0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x34,0x2c,0x6a,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x35,0x2c,
0x6a,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x36,0x2c,0x6a,0x36,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,
0x75,0x74,0x5b,0x37,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x37,0x2c,0x6a,0x37,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x38,0x5d,0x3d,0x50,0x4c,0x55,
0x53,0x28,0x78,0x38,0x2c,0x6a,0x38,0x5f,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x39,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x39,0x2c,0x6a,0x39,
0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x6a,0x31,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,
0x70,0x75,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x6a,0x31,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x32,
0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x6a,0x31,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,
0x28,0x78,0x31,0x33,0x2c,0x6a,0x31,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x6a,
0x31,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x6a,0x31,0x35,0x29,0x3b,0x0a,0x6f,
0x75,0x74,0x70,0x75,0x74,0x2b,0x3d,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x2f,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,
0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x36,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,
0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2b,0x33,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x70,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x74,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x5b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,
0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,
0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,
0x20,0x32,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,0x20,
0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,0x3e,0x20,0x63,0x29,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x5d,0x5b,0x52,0x4f,0x55,0x4e,0x44,0x53,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,
0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x7d,0x2c,0x0a,0x7b,0x30,0x55,
0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,0x30,
0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,
0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x7d,
0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x5b,0x32,0x35,0x5d,0x5b,
0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x36,0x34,0x7d,0x2c,0x7b,0x34,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x34,0x33,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,0x31,
0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x35,0x30,0x7d,0x2c,0x0a,0x7b,0x20,0x31,0x2c,0x36,0x33,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x35,0x38,0x7d,0x2c,0x7b,0x32,
0x35,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x34,0x36,0x7d,0x2c,0x0a,0x7b,0x36,0x32,0x2c,0x32,0x7d,0x2c,0x7b,0x35,
0x35,0x2c,0x39,0x7d,0x2c,0x7b,0x33,0x39,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x34,0x31,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x0a,0x7b,0x32,
0x38,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x34,0x35,0x2c,0x31,0x39,0x7d,0x2c,0x7b,0x36,
0x31,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x32,0x37,0x2c,0x33,0x37,0x7d,0x2c,0x7b,0x33,0x36,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x35,0x34,0x7d,0x2c,0x7b,0x31,
0x35,0x2c,0x34,0x39,0x7d,0x2c,0x7b,0x35,0x36,0x2c,0x38,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x69,0x6e,0x74,0x20,0x61,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x36,0x2c,0x31,0x32,0x2c,0x31,0x38,0x2c,0x32,0x34,0x2c,0x0a,0x31,0x2c,0x37,0x2c,0x31,
0x33,0x2c,0x31,0x39,0x2c,0x32,0x30,0x2c,0x0a,0x32,0x2c,0x38,0x2c,0x31,0x34,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x0a,0x33,0x2c,0x39,0x2c,0x31,0x30,0x2c,0x31,0x36,
0x2c,0x32,0x32,0x2c,0x0a,0x34,0x2c,0x35,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x32,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x2c,0x32,
0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x0a,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x0a,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x0a,0x34,0x2c,
0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,
0x63,0x5b,0x32,0x35,0x5d,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x31,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x7b,0x20,0x32,
0x2c,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x35,0x2c,0x36,0x2c,0x37,
0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x37,0x2c,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,0x39,
0x2c,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,0x32,
0x2c,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x2c,0x31,0x31,0x7d,0x2c,0x0a,0x7b,
0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x7d,0x2c,
0x7b,0x31,0x38,0x2c,0x31,0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,
0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x32,0x34,0x2c,0x32,
0x30,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,
0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x2c,0x0a,0x35,0x2c,0x36,0x2c,0x37,0x2c,0x38,
0x2c,0x39,0x2c,0x0a,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x0a,0x7d,0x3b,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,0x73,0x68,0x61,0x33,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,
0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,
0x65,0x74,0x5f,0x6c,0x6f,0x63,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,0x67,
0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,
0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,
0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,
0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,0x70,0x75,0x74,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,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x5d,
0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,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,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,
0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,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,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x77,0x6f,0x72,0x64,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x2b,0x2b,0x69,0x6e,0x70,0x75,0x74,0x29,0x0a,0x7b,0x0a,0x41,
0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x2b,0x2b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,
0x65,0x78,0x3b,0x0a,0x69,0x66,0x28,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x3d,0x31,0x37,0x29,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,
0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,
0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,
0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,
0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,
0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,
0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,
0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,
0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,
0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x3d,0x30,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,0x70,0x3d,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,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,
0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,0x28,0x75,
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,
0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,
0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,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,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,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,
0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,
0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,
0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,
0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,
0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,
0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,
0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,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,
0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,0x69,0x6e,0x69,
0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,
0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,
0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,
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,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,
0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,
0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x74,
0x3c,0x31,0x36,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x2a,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,
0x28,0x41,0x29,0x2b,0x39,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x3d,0x67,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x3d,0x28,0x6e,
0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x26,0x30,
0x78,0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x3d,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,
0x6f,0x73,0x5b,0x31,0x5d,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3e,0x3e,0x38,0x29,0x3b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,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,0x74,0x61,
0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,
0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,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,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,
0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,
0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,
0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,
0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,
0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,
0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,
0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,
0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,
0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,
0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View file

@ -1,153 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define ROTATE(v,c) (rotate(v,(uint32_t)c))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) ((v) + (w))
__attribute__((reqd_work_group_size(SALSA20_GROUP_SIZE, 1, 1)))
__kernel void Salsa20_XORKeyStream(__global const uint32_t* keys, __global uint32_t* outputs, __global uint32_t* output_sizes, uint32_t output_stride)
{
const uint32_t t = get_local_id(0);
const uint32_t g = get_group_id(0);
// Put zeroes in the beginning
const uint64_t output_offset = g * ((uint64_t)output_stride) + 128;
{
__global uint32_t* p = outputs + (output_offset - 128) / sizeof(uint32_t);
for (uint32_t i = t; i < 128 / sizeof(uint32_t); i += SALSA20_GROUP_SIZE)
p[i] = 0;
}
__global const uint32_t* k = keys + g * 8;
__global uint32_t* output = outputs + (output_offset + (t * 64)) / sizeof(uint32_t);
const uint32_t output_size = output_sizes[g];
const uint32_t j1 = k[0];
const uint32_t j2 = k[1];
const uint32_t j3 = k[2];
const uint32_t j4 = k[3];
const uint32_t j11 = k[4];
const uint32_t j12 = k[5];
const uint32_t j13 = k[6];
const uint32_t j14 = k[7];
const uint32_t j0 = 0x61707865U;
const uint32_t j5 = 0x3320646EU;
const uint32_t j10 = 0x79622D32U;
const uint32_t j15 = 0x6B206574U;
const uint32_t j6 = 0;
const uint32_t j7 = 0;
const uint32_t j8 = 0;
const uint32_t j9 = 0;
for (uint32_t i = t * 64; i < output_size; i += SALSA20_GROUP_SIZE * 64)
{
const uint32_t j8_1 = j8 + (i / 64);
uint32_t x0 = j0;
uint32_t x1 = j1;
uint32_t x2 = j2;
uint32_t x3 = j3;
uint32_t x4 = j4;
uint32_t x5 = j5;
uint32_t x6 = j6;
uint32_t x7 = j7;
uint32_t x8 = j8_1;
uint32_t x9 = j9;
uint32_t x10 = j10;
uint32_t x11 = j11;
uint32_t x12 = j12;
uint32_t x13 = j13;
uint32_t x14 = j14;
uint32_t x15 = j15;
#pragma unroll 5
for (uint32_t j = 0; j < 10; ++j)
{
x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7));
x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9));
x12 = XOR(x12,ROTATE(PLUS( x8, x4),13));
x0 = XOR( x0,ROTATE(PLUS(x12, x8),18));
x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7));
x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9));
x1 = XOR( x1,ROTATE(PLUS(x13, x9),13));
x5 = XOR( x5,ROTATE(PLUS( x1,x13),18));
x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7));
x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9));
x6 = XOR( x6,ROTATE(PLUS( x2,x14),13));
x10 = XOR(x10,ROTATE(PLUS( x6, x2),18));
x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7));
x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9));
x11 = XOR(x11,ROTATE(PLUS( x7, x3),13));
x15 = XOR(x15,ROTATE(PLUS(x11, x7),18));
x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7));
x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9));
x3 = XOR( x3,ROTATE(PLUS( x2, x1),13));
x0 = XOR( x0,ROTATE(PLUS( x3, x2),18));
x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7));
x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9));
x4 = XOR( x4,ROTATE(PLUS( x7, x6),13));
x5 = XOR( x5,ROTATE(PLUS( x4, x7),18));
x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7));
x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9));
x9 = XOR( x9,ROTATE(PLUS( x8,x11),13));
x10 = XOR(x10,ROTATE(PLUS( x9, x8),18));
x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7));
x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9));
x14 = XOR(x14,ROTATE(PLUS(x13,x12),13));
x15 = XOR(x15,ROTATE(PLUS(x14,x13),18));
}
output[0] = PLUS(x0, j0);
output[1] = PLUS(x1, j1);
output[2] = PLUS(x2, j2);
output[3] = PLUS(x3, j3);
output[4] = PLUS(x4, j4);
output[5] = PLUS(x5, j5);
output[6] = PLUS(x6, j6);
output[7] = PLUS(x7, j7);
output[8] = PLUS(x8, j8_1);
output[9] = PLUS(x9, j9);
output[10] = PLUS(x10,j10);
output[11] = PLUS(x11,j11);
output[12] = PLUS(x12,j12);
output[13] = PLUS(x13,j13);
output[14] = PLUS(x14,j14);
output[15] = PLUS(x15,j15);
output += (SALSA20_GROUP_SIZE * 64) / sizeof(uint32_t);
}
barrier(CLK_GLOBAL_MEM_FENCE);
// Put zeroes after output's end
if (t < 16)
{
__global uint32_t* p = outputs + (output_offset + output_size + 3) / sizeof(uint32_t);
p[t] = 0;
}
if ((t == 0) && (output_size & 3))
outputs[(output_offset + output_size) / sizeof(uint32_t)] &= 0xFFFFFFFFU >> ((4 - (output_size & 3)) << 3);
}

View file

@ -1,198 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define ROUNDS 24
#define R64(a,b,c) (((a) << b) | ((a) >> c))
__constant const uint64_t rc[2][ROUNDS] = {
{0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL,
0x8000000080008000UL, 0x000000000000808BUL, 0x0000000080000001UL,
0x8000000080008081UL, 0x8000000000008009UL, 0x000000000000008AUL,
0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL,
0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL,
0x8000000000008003UL, 0x8000000000008002UL, 0x8000000000000080UL,
0x000000000000800AUL, 0x800000008000000AUL, 0x8000000080008081UL,
0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL},
{0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL,
0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL,
0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}
};
__constant const int ro[25][2] = {
{ 0,64}, {44,20}, {43,21}, {21,43}, {14,50},
{ 1,63}, { 6,58}, {25,39}, { 8,56}, {18,46},
{62, 2}, {55, 9}, {39,25}, {41,23}, { 2,62},
{28,36}, {20,44}, { 3,61}, {45,19}, {61, 3},
{27,37}, {36,28}, {10,54}, {15,49}, {56, 8}
};
__constant const int a[25] = {
0, 6, 12, 18, 24,
1, 7, 13, 19, 20,
2, 8, 14, 15, 21,
3, 9, 10, 16, 22,
4, 5, 11, 17, 23
};
__constant const int b[25] = {
0, 1, 2, 3, 4,
1, 2, 3, 4, 0,
2, 3, 4, 0, 1,
3, 4, 0, 1, 2,
4, 0, 1, 2, 3
};
__constant const int c[25][3] = {
{ 0, 1, 2}, { 1, 2, 3}, { 2, 3, 4}, { 3, 4, 0}, { 4, 0, 1},
{ 5, 6, 7}, { 6, 7, 8}, { 7, 8, 9}, { 8, 9, 5}, { 9, 5, 6},
{10,11,12}, {11,12,13}, {12,13,14}, {13,14,10}, {14,10,11},
{15,16,17}, {16,17,18}, {17,18,19}, {18,19,15}, {19,15,16},
{20,21,22}, {21,22,23}, {22,23,24}, {23,24,20}, {24,20,21}
};
__constant const int d[25] = {
0, 1, 2, 3, 4,
10, 11, 12, 13, 14,
20, 21, 22, 23, 24,
5, 6, 7, 8, 9,
15, 16, 17, 18, 19
};
__attribute__((reqd_work_group_size(32, 1, 1)))
__kernel void sha3(__global const uint8_t* inputs, __global const uint32_t* input_sizes, uint32_t input_stride, __global uint64_t* hashes)
{
const uint32_t t = get_local_id(0);
const uint32_t g = get_group_id(0);
if (t >= 25)
return;
const uint32_t s = t % 5;
const uint64_t input_offset = ((uint64_t)input_stride) * g;
__global uint64_t* input = (__global uint64_t*)(inputs + input_offset);
const uint32_t input_size = input_sizes[g] + 1;
__local uint64_t A[25];
__local uint64_t C[25];
__local uint64_t D[25];
A[t] = 0;
const uint32_t words = input_size / sizeof(uint64_t);
const uint32_t tail_size = input_size % sizeof(uint64_t);
uint32_t wordIndex = 0;
for (uint32_t i = 0; i < words; ++i, ++input)
{
A[wordIndex] ^= *input;
++wordIndex;
if (wordIndex == 17)
{
#pragma unroll ROUNDS
for (int i = 0; i < ROUNDS; ++i)
{
C[t] = A[s] ^ A[s+5] ^ A[s+10] ^ A[s+15] ^ A[s+20];
D[t] = C[b[20+s]] ^ R64(C[b[5+s]], 1, 63);
C[t] = R64(A[a[t]] ^ D[b[t]], ro[t][0], ro[t][1]);
A[d[t]] = C[c[t][0]] ^ ((~C[c[t][1]]) & C[c[t][2]]);
A[t] ^= rc[(t == 0) ? 0 : 1][i];
}
wordIndex = 0;
}
}
uint64_t tail = 0;
__global const uint8_t* p = (__global const uint8_t*)input;
for (uint32_t i = 0; i < tail_size; ++i)
{
tail |= (uint64_t)(p[i]) << (i * 8);
}
A[wordIndex] ^= tail ^ ((uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8)));
A[16] ^= 0x8000000000000000UL;
#pragma unroll 1
for (int i = 0; i < ROUNDS; ++i)
{
C[t] = A[s] ^ A[s+5] ^ A[s+10] ^ A[s+15] ^ A[s+20];
D[t] = C[b[20+s]] ^ R64(C[b[5+s]], 1, 63);
C[t] = R64(A[a[t]] ^ D[b[t]], ro[t][0], ro[t][1]);
A[d[t]] = C[c[t][0]] ^ ((~C[c[t][1]]) & C[c[t][2]]);
A[t] ^= rc[(t == 0) ? 0 : 1][i];
}
if (t < 4)
{
hashes += g * (32 / sizeof(uint64_t));
hashes[t] = A[t];
}
}
__attribute__((reqd_work_group_size(32, 1, 1)))
__kernel void sha3_initial(__global const uint8_t* input_data, uint32_t input_size, uint32_t nonce, __global uint64_t* hashes)
{
const uint32_t t = get_local_id(0);
const uint32_t g = get_group_id(0);
if (t >= 25)
return;
const uint32_t s = t % 5;
__global uint64_t* input = (__global uint64_t*)(input_data);
__local uint64_t A[25];
__local uint64_t C[25];
__local uint64_t D[25];
A[t] = (t < 16) ? input[t] : 0;
__local uint32_t* nonce_pos = (__local uint32_t*)(A) + 9;
nonce += g;
nonce_pos[0] = (nonce_pos[0] & 0xFFFFFFU) | ((nonce & 0xFF) << 24);
nonce_pos[1] = (nonce_pos[1] & 0xFF000000U) | (nonce >> 8);
uint32_t wordIndex = input_size / sizeof(uint64_t);
const uint32_t tail_size = input_size % sizeof(uint64_t);
A[wordIndex] ^= (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8));
A[16] ^= 0x8000000000000000UL;
#pragma unroll ROUNDS
for (int i = 0; i < ROUNDS; ++i)
{
C[t] = A[s] ^ A[s+5] ^ A[s+10] ^ A[s+15] ^ A[s+20];
D[t] = C[b[20+s]] ^ R64(C[b[5+s]], 1, 63);
C[t] = R64(A[a[t]] ^ D[b[t]], ro[t][0], ro[t][1]);
A[d[t]] = C[c[t][0]] ^ ((~C[c[t][1]]) & C[c[t][2]]);
A[t] ^= rc[(t == 0) ? 0 : 1][i];
}
if (t < 4)
{
hashes += g * (32 / sizeof(uint64_t));
hashes[t] = A[t];
}
}

View file

@ -1,179 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2022 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define BLOCK_SIZE 1024
#define DATA_SIZE 9973
#define DATA_STRIDE 10240
#define BITS 14
#define COUNTERS_SIZE (1 << BITS)
inline uint16_t atomic_inc16(__local uint16_t* value)
{
const size_t k = (size_t) value;
if ((k & 3) == 0) {
return atomic_add((__local uint32_t*) value, 1);
}
return atomic_add((__local uint32_t*)(k - 2), 0x10000) >> 16;
}
__attribute__((reqd_work_group_size(BLOCK_SIZE, 1, 1)))
__kernel void BWT_preprocess(__global const uint8_t* datas, __global uint32_t* keys)
{
const uint32_t data_offset = get_group_id(0) * DATA_STRIDE;
const uint32_t tid = get_local_id(0);
__local uint32_t counters_buf[COUNTERS_SIZE / 2];
__local uint16_t* counters = (__local uint16_t*) counters_buf;
for (uint32_t i = tid; i < COUNTERS_SIZE / 2; i += BLOCK_SIZE) {
counters_buf[i] = 0;
}
barrier(CLK_LOCAL_MEM_FENCE);
datas += data_offset;
keys += data_offset;
for (uint32_t i = tid; i < DATA_SIZE; i += BLOCK_SIZE) {
const uint32_t k0 = datas[i];
const uint32_t k1 = datas[i + 1];
const uint32_t k = ((k0 << 8) | k1) >> (16 - BITS);
atomic_inc16(counters + k);
}
barrier(CLK_LOCAL_MEM_FENCE);
#pragma unroll BITS
for (int k = 0; k < BITS; ++k) {
for (uint32_t t1 = tid; t1 < ((COUNTERS_SIZE / 2) >> k); t1 += BLOCK_SIZE) {
const uint32_t i = (t1 << (k + 1)) + ((1 << (k + 1)) - 1);
counters[i] += counters[i - (1 << k)];
}
barrier(CLK_LOCAL_MEM_FENCE);
}
if (tid == 0) {
counters[COUNTERS_SIZE - 1] = 0;
}
barrier(CLK_LOCAL_MEM_FENCE);
#pragma unroll BITS
for (int k = BITS - 1; k >= 0; --k) {
for (uint32_t t1 = tid; t1 < ((COUNTERS_SIZE / 2) >> k); t1 += BLOCK_SIZE) {
const uint32_t i = (t1 << (k + 1)) + ((1 << (k + 1)) - 1);
const uint16_t old = counters[i];
counters[i] = old + counters[i - (1 << k)];
counters[i - (1 << k)] = old;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
for (uint32_t i = tid; i < DATA_SIZE; i += BLOCK_SIZE) {
const uint32_t k0 = datas[i];
const uint32_t k1 = datas[i + 1];
const uint32_t k = (k0 << 8) | k1;
const uint32_t index = atomic_inc16(counters + (k >> (16 - BITS)));
keys[index] = (k << 16) | i;
}
}
inline void fix_order(__global const uint8_t* input, uint32_t a, uint32_t b, __global uint32_t* keys)
{
const uint32_t ka = keys[a];
const uint32_t kb = keys[b];
const uint32_t index_a = ka & 0xFFFF;
const uint32_t index_b = kb & 0xFFFF;
const uint32_t value_a =
(((uint32_t)input[index_a + 1]) << 24) |
(((uint32_t)input[index_a + 2]) << 16) |
(((uint32_t)input[index_a + 3]) << 8) |
((uint32_t)input[index_a + 4]);
const uint32_t value_b =
(((uint32_t)input[index_b + 1]) << 24) |
(((uint32_t)input[index_b + 2]) << 16) |
(((uint32_t)input[index_b + 3]) << 8) |
((uint32_t)input[index_b + 4]);
if (value_a > value_b)
{
keys[a] = kb;
keys[b] = ka;
}
}
__attribute__((reqd_work_group_size(BLOCK_SIZE, 1, 1)))
__kernel void BWT_fix_order(__global const uint8_t* datas, __global uint32_t* keys, __global uint16_t* values)
{
const uint32_t tid = get_local_id(0);
const uint32_t gid = get_group_id(0);
const uint32_t data_offset = gid * 10240;
const uint32_t N = 9973;
datas += data_offset;
keys += data_offset;
values += data_offset;
for (uint32_t i = tid, N1 = N - 1; i < N1; i += BLOCK_SIZE)
{
const uint32_t value = keys[i] >> (32 - BITS);
if (value == (keys[i + 1] >> (32 - BITS)))
{
if (i && (value == (keys[i - 1] >> (32 - BITS))))
continue;
uint32_t n = i + 2;
while ((n < N) && (value == (keys[n] >> (32 - BITS))))
++n;
for (uint32_t j = i; j < n; ++j)
for (uint32_t k = j + 1; k < n; ++k)
fix_order(datas, j, k, keys);
}
}
barrier(CLK_GLOBAL_MEM_FENCE);
for (uint32_t i = tid; i < N; i += BLOCK_SIZE) {
values[i] = keys[i];
}
}
__kernel void find_shares(__global const uint64_t* hashes, uint64_t target, __global uint32_t* shares)
{
const uint32_t global_index = get_global_id(0);
if (hashes[global_index * 4 + 3] >= target) {
return;
}
const uint32_t idx = atomic_inc(shares + 0xFF);
if (idx < 0xFF)
shares[idx] = global_index;
}
#undef BLOCK_SIZE
#undef DATA_SIZE
#undef DATA_STRIDE
#undef BITS
#undef COUNTERS_SIZE

View file

@ -1,35 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2022 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
typedef uchar uint8_t;
typedef ushort uint16_t;
typedef uint uint32_t;
typedef ulong uint64_t;
typedef int int32_t;
typedef long int64_t;
#include "BWT.cl"
#include "salsa20.cl"
#include "sha3.cl"

View file

@ -1,388 +0,0 @@
#pragma once
namespace xmrig {
static const char astrobwt_v2_cl[12139] = {
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,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x30,0x32,
0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,0x20,0x39,0x39,0x37,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,
0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,0x44,0x45,0x20,0x31,0x30,0x32,0x34,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x42,0x49,0x54,0x53,0x20,
0x31,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x31,0x20,0x3c,0x3c,0x20,0x42,
0x49,0x54,0x53,0x29,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x31,
0x36,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x73,0x69,0x7a,0x65,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x73,0x69,0x7a,0x65,0x5f,0x74,0x29,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x69,0x66,0x28,0x28,
0x6b,0x26,0x33,0x29,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x5f,0x5f,
0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x20,0x76,0x61,0x6c,0x75,0x65,0x2c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,
0x75,0x72,0x6e,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x2a,0x29,0x28,0x6b,0x2d,0x32,0x29,0x2c,0x30,0x78,0x31,0x30,0x30,0x30,0x30,0x29,0x3e,0x3e,0x31,0x36,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,0x42,0x4c,0x4f,0x43,
0x4b,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x42,0x57,0x54,0x5f,
0x70,0x72,0x65,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x28,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,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,
0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,0x44,0x45,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,
0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x5b,0x43,0x4f,
0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,
0x2a,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x29,0x20,0x63,
0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,
0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,
0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,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,0x64,0x61,0x74,0x61,0x73,0x2b,0x3d,
0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,
0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6b,0x30,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x31,
0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x28,
0x6b,0x30,0x3c,0x3c,0x38,0x29,0x7c,0x6b,0x31,0x29,0x3e,0x3e,0x28,0x31,0x36,0x2d,0x42,0x49,0x54,0x53,0x29,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,
0x63,0x31,0x36,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x2b,0x6b,0x29,0x3b,0x0a,0x7d,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,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,
0x42,0x49,0x54,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x30,0x3b,0x20,0x6b,0x3c,0x42,0x49,0x54,0x53,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,
0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x31,0x3d,0x74,0x69,0x64,0x3b,0x20,0x74,0x31,0x3c,0x28,0x28,0x43,0x4f,0x55,
0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x29,0x3e,0x3e,0x6b,0x29,0x3b,0x20,0x74,0x31,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,
0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x28,0x74,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,
0x29,0x2b,0x28,0x28,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x2b,0x3d,0x63,
0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,0x3c,0x3c,0x6b,0x29,0x5d,0x3b,0x0a,0x7d,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,0x7d,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x20,
0x7b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,
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,0x23,
0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x42,0x49,0x54,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x42,0x49,
0x54,0x53,0x2d,0x31,0x3b,0x20,0x6b,0x3e,0x3d,0x30,0x3b,0x20,0x2d,0x2d,0x6b,0x29,0x20,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x74,0x31,0x3d,0x74,0x69,0x64,0x3b,0x20,0x74,0x31,0x3c,0x28,0x28,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x29,0x3e,0x3e,
0x6b,0x29,0x3b,0x20,0x74,0x31,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x28,0x74,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2b,0x28,0x28,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2d,0x31,
0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x6f,0x6c,0x64,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,
0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x3d,0x6f,0x6c,0x64,0x2b,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,
0x3c,0x3c,0x6b,0x29,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,0x3c,0x3c,0x6b,0x29,0x5d,0x3d,0x6f,0x6c,0x64,0x3b,0x0a,0x7d,
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,0x7d,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,
0x45,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x6b,0x30,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,
0x31,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,
0x6b,0x30,0x3c,0x3c,0x38,0x29,0x7c,0x6b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,
0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x31,0x36,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x2b,0x28,0x6b,0x3e,0x3e,0x28,0x31,0x36,0x2d,0x42,0x49,
0x54,0x53,0x29,0x29,0x29,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x28,0x6b,0x3c,0x3c,0x31,0x36,0x29,0x7c,0x69,0x3b,0x0a,0x7d,0x0a,
0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,
0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,
0x65,0x79,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x61,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x61,0x5d,
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x62,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x62,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x3d,0x6b,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,0x0a,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x3d,0x6b,0x62,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x31,0x5d,0x29,0x3c,0x3c,0x32,0x34,0x29,0x20,0x7c,0x0a,0x28,
0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x32,0x5d,0x29,0x3c,0x3c,0x31,0x36,
0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x33,0x5d,
0x29,0x3c,0x3c,0x38,0x29,0x20,0x7c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,
0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x0a,0x28,
0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x2b,0x31,0x5d,0x29,0x3c,0x3c,0x32,0x34,
0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x2b,0x32,0x5d,
0x29,0x3c,0x3c,0x31,0x36,0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,
0x5f,0x62,0x2b,0x33,0x5d,0x29,0x3c,0x3c,0x38,0x29,0x20,0x7c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,
0x64,0x65,0x78,0x5f,0x62,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x3e,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x29,0x0a,0x7b,
0x0a,0x6b,0x65,0x79,0x73,0x5b,0x61,0x5d,0x3d,0x6b,0x62,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x5b,0x62,0x5d,0x3d,0x6b,0x61,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,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,
0x20,0x42,0x57,0x54,0x5f,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,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,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,
0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x73,0x29,0x0a,
0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,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,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,
0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,
0x66,0x73,0x65,0x74,0x3d,0x67,0x69,0x64,0x2a,0x31,0x30,0x32,0x34,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,
0x3d,0x39,0x39,0x37,0x33,0x3b,0x0a,0x64,0x61,0x74,0x61,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x2b,
0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x76,0x61,0x6c,0x75,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,
0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x2c,0x4e,0x31,0x3d,0x4e,0x2d,0x31,0x3b,0x20,0x69,
0x3c,0x4e,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x69,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x3b,0x0a,0x69,
0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,
0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x26,0x26,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,0x69,0x2d,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,
0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x3d,0x69,
0x2b,0x32,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x6e,0x3c,0x4e,0x29,0x26,0x26,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,
0x6e,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,0x29,0x0a,0x2b,0x2b,0x6e,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x6a,0x3d,0x69,0x3b,0x20,0x6a,0x3c,0x6e,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x6b,0x3d,0x6a,0x2b,0x31,0x3b,0x20,0x6b,0x3c,0x6e,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,0x64,0x61,0x74,0x61,
0x73,0x2c,0x6a,0x2c,0x6b,0x2c,0x6b,0x65,0x79,0x73,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,
0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,
0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x76,0x61,0x6c,0x75,0x65,
0x73,0x5b,0x69,0x5d,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,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,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,0x3e,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,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,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x67,0x6c,0x6f,
0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x0a,0x23,
0x75,0x6e,0x64,0x65,0x66,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,
0x44,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x42,0x49,0x54,0x53,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,
0x49,0x5a,0x45,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x76,0x2c,0x63,0x29,0x20,0x28,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,
0x76,0x2c,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x63,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4f,0x52,0x28,0x76,0x2c,0x77,0x29,
0x20,0x28,0x28,0x76,0x29,0x20,0x5e,0x20,0x28,0x77,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x55,0x53,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,
0x28,0x76,0x29,0x20,0x2b,0x20,0x28,0x77,0x29,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,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,
0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x61,0x6c,0x73,0x61,0x32,0x30,0x5f,0x58,
0x4f,0x52,0x4b,0x65,0x79,0x53,0x74,0x72,0x65,0x61,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,
0x70,0x75,0x74,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,
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,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,
0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,
0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,0x2a,0x31,0x30,0x32,0x34,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x3d,0x6b,0x65,0x79,0x73,0x2b,0x67,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,
0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x74,0x2a,0x36,0x34,0x29,0x29,0x2f,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,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x39,0x39,0x37,
0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x3d,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x32,0x3d,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x6a,0x33,0x3d,0x6b,0x5b,0x32,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x34,0x3d,0x6b,0x5b,0x33,
0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x31,0x3d,0x6b,0x5b,0x34,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x32,0x3d,0x6b,0x5b,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x6a,0x31,0x33,0x3d,0x6b,0x5b,0x36,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x34,
0x3d,0x6b,0x5b,0x37,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x30,0x3d,0x30,0x78,0x36,0x31,0x37,0x30,0x37,
0x38,0x36,0x35,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x35,0x3d,0x30,0x78,0x33,0x33,0x32,0x30,0x36,0x34,
0x36,0x45,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x30,0x3d,0x30,0x78,0x37,0x39,0x36,0x32,0x32,0x44,
0x33,0x32,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x35,0x3d,0x30,0x78,0x36,0x42,0x32,0x30,0x36,0x35,
0x37,0x34,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x36,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x37,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,
0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x39,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x2a,0x36,0x34,0x3b,0x20,0x69,0x3c,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,
0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x5f,0x31,0x3d,0x6a,0x38,0x2b,0x28,0x69,0x2f,0x36,0x34,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x78,0x30,0x3d,0x6a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x3d,0x6a,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x78,0x32,0x3d,0x6a,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x33,0x3d,0x6a,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x78,0x34,0x3d,0x6a,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x35,0x3d,0x6a,0x35,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x78,0x36,0x3d,0x6a,0x36,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x37,0x3d,0x6a,0x37,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x78,0x38,0x3d,0x6a,0x38,0x5f,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x39,0x3d,0x6a,0x39,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x78,0x31,0x30,0x3d,0x6a,0x31,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x31,0x3d,0x6a,0x31,0x31,0x3b,0x0a,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x32,0x3d,0x6a,0x31,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x33,0x3d,0x6a,0x31,
0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x34,0x3d,0x6a,0x31,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,
0x35,0x3d,0x6a,0x31,0x35,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x35,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,
0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x31,0x32,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,
0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,
0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x34,0x29,
0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
0x32,0x2c,0x78,0x38,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,
0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x39,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,
0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,
0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x36,0x29,0x2c,
0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,
0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,
0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,
0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,
0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x33,0x29,0x2c,
0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
0x31,0x2c,0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x33,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,
0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,
0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,
0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x36,
0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x34,0x29,0x2c,0x37,0x29,0x29,
0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x35,0x29,
0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,
0x2c,0x78,0x36,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,
0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x39,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,
0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,
0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x31,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,
0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x38,0x29,0x2c,
0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
0x35,0x2c,0x78,0x31,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,
0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x31,0x32,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,
0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,
0x7d,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x30,0x2c,0x6a,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,
0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x2c,0x6a,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,
0x32,0x2c,0x6a,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x33,0x2c,0x6a,0x33,0x29,0x3b,0x0a,0x6f,0x75,
0x74,0x70,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x34,0x2c,0x6a,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x50,
0x4c,0x55,0x53,0x28,0x78,0x35,0x2c,0x6a,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x36,0x2c,0x6a,0x36,
0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x37,0x2c,0x6a,0x37,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,
0x5b,0x38,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x38,0x2c,0x6a,0x38,0x5f,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x39,0x5d,0x3d,0x50,0x4c,0x55,
0x53,0x28,0x78,0x39,0x2c,0x6a,0x39,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x6a,0x31,
0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x6a,0x31,0x31,0x29,0x3b,0x0a,0x6f,0x75,
0x74,0x70,0x75,0x74,0x5b,0x31,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x6a,0x31,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,
0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x6a,0x31,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x50,0x4c,0x55,
0x53,0x28,0x78,0x31,0x34,0x2c,0x6a,0x31,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,
0x6a,0x31,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x3d,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,
0x45,0x2a,0x36,0x34,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,
0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x36,
0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,
0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2b,0x33,0x29,0x2f,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x70,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x74,
0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x5b,0x28,
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,
0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,
0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,
0x52,0x4f,0x54,0x41,0x54,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x58,0x4f,0x52,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x55,0x53,0x0a,0x23,0x64,
0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x20,0x32,0x34,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5b,0x32,0x35,0x5d,0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x32,0x2c,
0x33,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x36,0x2c,0x37,0x7d,0x2c,
0x7b,0x20,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x31,
0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x30,
0x2c,0x31,0x31,0x7d,0x2c,0x0a,0x7b,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x31,0x39,0x7d,0x2c,0x7b,0x31,
0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x31,0x2c,0x32,0x32,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,
0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,
0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x70,0x69,0x5b,0x32,0x35,0x5d,0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x2c,0x30,
0x7d,0x2c,0x7b,0x36,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x31,0x32,0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x31,0x34,0x7d,
0x2c,0x7b,0x33,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x39,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x33,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x34,0x35,0x7d,0x2c,0x0a,0x7b,
0x32,0x32,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x31,0x2c,0x31,0x7d,0x2c,0x7b,0x37,0x2c,0x36,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x38,
0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x34,0x2c,0x32,0x37,0x7d,0x2c,0x7b,0x35,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x30,0x7d,0x2c,
0x0a,0x7b,0x31,0x37,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x7b,0x38,0x2c,0x35,0x35,0x7d,0x2c,0x7b,
0x31,0x34,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x31,0x35,0x2c,0x34,0x31,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x7d,0x0a,0x7d,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,
0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,0x20,0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,
0x3e,0x20,0x63,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x6b,0x29,0x20,0x5c,0x0a,0x64,0x6f,0x20,0x7b,0x20,0x5c,0x0a,
0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,
0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x20,0x5c,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x43,0x5b,0x73,0x2b,0x34,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,
0x5b,0x73,0x2b,0x31,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x20,0x5c,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x74,0x5d,0x2c,0x72,0x6f,
0x30,0x2c,0x72,0x6f,0x31,0x29,0x3b,0x20,0x5c,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x43,0x5b,0x74,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x31,0x5d,0x29,0x26,0x43,
0x5b,0x63,0x32,0x5d,0x29,0x29,0x5e,0x28,0x6b,0x31,0x26,0x28,0x6b,0x29,0x29,0x3b,0x20,0x5c,0x0a,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,0x73,0x68,0x61,0x33,0x28,
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,
0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x31,0x30,0x32,0x34,0x30,0x2a,0x32,0x2a,0x67,0x3b,0x0a,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,0x69,0x6e,0x70,0x75,0x74,0x3d,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,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,
0x70,0x75,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,0x20,0x41,0x5b,
0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,
0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x74,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,
0x6f,0x30,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x31,0x3d,0x36,0x34,0x2d,0x72,
0x6f,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x69,0x6e,0x74,0x20,0x63,0x32,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,
0x31,0x3d,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x4c,0x3a,0x30,0x55,
0x4c,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x39,0x39,0x37,
0x33,0x2a,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3d,
0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,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,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x70,0x75,
0x74,0x5f,0x65,0x6e,0x64,0x31,0x37,0x3d,0x69,0x6e,0x70,0x75,0x74,0x2b,0x28,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x2f,0x31,0x37,0x29,0x2a,
0x31,0x37,0x29,0x3b,0x0a,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,0x63,0x6f,
0x6e,0x73,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x3d,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3b,
0x0a,0x66,0x6f,0x72,0x20,0x28,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x3c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x31,0x37,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,
0x2b,0x3d,0x31,0x37,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x37,0x29,0x20,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,
0x5d,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,
0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,
0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,
0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,
0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,
0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,
0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,
0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,
0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,
0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,
0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,
0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,
0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x29,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x2d,
0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x29,0x20,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x69,
0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,
0x6c,0x3d,0x30,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,0x70,0x3d,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,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,
0x64,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,
0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,
0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,
0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,
0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,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,0x7d,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,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,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x43,
0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,
0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x43,0x5b,0x73,0x2b,0x34,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x73,0x2b,
0x31,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x74,0x5d,0x2c,0x72,0x6f,0x30,0x2c,0x72,0x6f,0x31,
0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x43,0x5b,0x74,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x31,0x5d,0x29,0x26,0x43,0x5b,0x63,0x32,0x5d,0x29,0x29,0x5e,
0x28,0x72,0x63,0x5b,0x69,0x5d,0x26,0x6b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x20,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,
0x2a,0x34,0x2b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,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,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,
0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,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,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,
0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,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,0x69,0x6e,0x70,0x75,0x74,0x3d,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,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,
0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,
0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x74,0x3c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,
0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x2a,0x29,0x41,0x29,0x5b,0x31,0x31,0x5d,0x3d,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x67,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,
0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x5d,0x20,0x5e,0x3d,0x20,0x28,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,
0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,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,0x7d,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,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x74,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,
0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x30,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x31,0x3d,0x36,0x34,0x2d,0x72,0x6f,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x3d,
0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x32,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x31,0x3d,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
0x74,0x29,0x28,0x2d,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,
0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,
0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,
0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,
0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,
0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,
0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,
0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,
0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,
0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,
0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x29,
0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x20,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x2a,0x34,0x2b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,
0x7d,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x52,0x36,0x34,0x0a,0x23,0x75,0x6e,
0x64,0x65,0x66,0x20,0x52,0x4f,0x55,0x4e,0x44,0x0a,0x00
};
} // namespace xmrig

View file

@ -1,151 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2022 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define ROTATE(v,c) (rotate(v,(uint32_t)c))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) ((v) + (w))
__attribute__((reqd_work_group_size(SALSA20_GROUP_SIZE, 1, 1)))
__kernel void Salsa20_XORKeyStream(__global const uint32_t* keys, __global uint32_t* outputs)
{
const uint32_t t = get_local_id(0);
const uint32_t g = get_group_id(0);
const uint64_t output_offset = g * 10240;
__global const uint32_t* k = keys + g * 8;
__global uint32_t* output = outputs + (output_offset + (t * 64)) / sizeof(uint32_t);
const uint32_t output_size = 9973;
const uint32_t j1 = k[0];
const uint32_t j2 = k[1];
const uint32_t j3 = k[2];
const uint32_t j4 = k[3];
const uint32_t j11 = k[4];
const uint32_t j12 = k[5];
const uint32_t j13 = k[6];
const uint32_t j14 = k[7];
const uint32_t j0 = 0x61707865U;
const uint32_t j5 = 0x3320646EU;
const uint32_t j10 = 0x79622D32U;
const uint32_t j15 = 0x6B206574U;
const uint32_t j6 = 0;
const uint32_t j7 = 0;
const uint32_t j8 = 0;
const uint32_t j9 = 0;
for (uint32_t i = t * 64; i < output_size; i += SALSA20_GROUP_SIZE * 64)
{
const uint32_t j8_1 = j8 + (i / 64);
uint32_t x0 = j0;
uint32_t x1 = j1;
uint32_t x2 = j2;
uint32_t x3 = j3;
uint32_t x4 = j4;
uint32_t x5 = j5;
uint32_t x6 = j6;
uint32_t x7 = j7;
uint32_t x8 = j8_1;
uint32_t x9 = j9;
uint32_t x10 = j10;
uint32_t x11 = j11;
uint32_t x12 = j12;
uint32_t x13 = j13;
uint32_t x14 = j14;
uint32_t x15 = j15;
#pragma unroll 5
for (uint32_t j = 0; j < 10; ++j)
{
x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7));
x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9));
x12 = XOR(x12,ROTATE(PLUS( x8, x4),13));
x0 = XOR( x0,ROTATE(PLUS(x12, x8),18));
x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7));
x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9));
x1 = XOR( x1,ROTATE(PLUS(x13, x9),13));
x5 = XOR( x5,ROTATE(PLUS( x1,x13),18));
x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7));
x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9));
x6 = XOR( x6,ROTATE(PLUS( x2,x14),13));
x10 = XOR(x10,ROTATE(PLUS( x6, x2),18));
x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7));
x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9));
x11 = XOR(x11,ROTATE(PLUS( x7, x3),13));
x15 = XOR(x15,ROTATE(PLUS(x11, x7),18));
x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7));
x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9));
x3 = XOR( x3,ROTATE(PLUS( x2, x1),13));
x0 = XOR( x0,ROTATE(PLUS( x3, x2),18));
x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7));
x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9));
x4 = XOR( x4,ROTATE(PLUS( x7, x6),13));
x5 = XOR( x5,ROTATE(PLUS( x4, x7),18));
x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7));
x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9));
x9 = XOR( x9,ROTATE(PLUS( x8,x11),13));
x10 = XOR(x10,ROTATE(PLUS( x9, x8),18));
x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7));
x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9));
x14 = XOR(x14,ROTATE(PLUS(x13,x12),13));
x15 = XOR(x15,ROTATE(PLUS(x14,x13),18));
}
output[0] = PLUS(x0, j0);
output[1] = PLUS(x1, j1);
output[2] = PLUS(x2, j2);
output[3] = PLUS(x3, j3);
output[4] = PLUS(x4, j4);
output[5] = PLUS(x5, j5);
output[6] = PLUS(x6, j6);
output[7] = PLUS(x7, j7);
output[8] = PLUS(x8, j8_1);
output[9] = PLUS(x9, j9);
output[10] = PLUS(x10,j10);
output[11] = PLUS(x11,j11);
output[12] = PLUS(x12,j12);
output[13] = PLUS(x13,j13);
output[14] = PLUS(x14,j14);
output[15] = PLUS(x15,j15);
output += (SALSA20_GROUP_SIZE * 64) / sizeof(uint32_t);
}
barrier(CLK_GLOBAL_MEM_FENCE);
// Put zeroes after output's end
if (t < 16)
{
__global uint32_t* p = outputs + (output_offset + output_size + 3) / sizeof(uint32_t);
p[t] = 0;
}
if ((t == 0) && (output_size & 3))
outputs[(output_offset + output_size) / sizeof(uint32_t)] &= 0xFFFFFFFFU >> ((4 - (output_size & 3)) << 3);
}
#undef ROTATE
#undef XOR
#undef PLUS

View file

@ -1,188 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2022 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#define ROUNDS 24
__constant const uint64_t rc[24] = {
0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL,
0x8000000080008000UL, 0x000000000000808BUL, 0x0000000080000001UL,
0x8000000080008081UL, 0x8000000000008009UL, 0x000000000000008AUL,
0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL,
0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL,
0x8000000000008003UL, 0x8000000000008002UL, 0x8000000000000080UL,
0x000000000000800AUL, 0x800000008000000AUL, 0x8000000080008081UL,
0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
};
__constant const int c[25][2] = {
{ 1, 2}, { 2, 3}, { 3, 4}, { 4, 0}, { 0, 1},
{ 6, 7}, { 7, 8}, { 8, 9}, { 9, 5}, { 5, 6},
{11,12}, {12,13}, {13,14}, {14,10}, {10,11},
{16,17}, {17,18}, {18,19}, {19,15}, {15,16},
{21,22}, {22,23}, {23,24}, {24,20}, {20,21}
};
__constant const int ppi[25][2] = {
{0, 0}, {6, 44}, {12, 43}, {18, 21}, {24, 14}, {3, 28}, {9, 20}, {10, 3}, {16, 45},
{22, 61}, {1, 1}, {7, 6}, {13, 25}, {19, 8}, {20, 18}, {4, 27}, {5, 36}, {11, 10},
{17, 15}, {23, 56}, {2, 62}, {8, 55}, {14, 39}, {15, 41}, {21, 2}
};
#define R64(a,b,c) (((a) << b) | ((a) >> c))
#define ROUND(k) \
do { \
C[t] = A[s] ^ A[s + 5] ^ A[s + 10] ^ A[s + 15] ^ A[s + 20]; \
A[t] ^= C[s + 4] ^ R64(C[s + 1], 1, 63); \
C[t] = R64(A[at], ro0, ro1); \
A[t] = (C[t] ^ ((~C[c1]) & C[c2])) ^ (k1 & (k)); \
} while (0)
__attribute__((reqd_work_group_size(32, 1, 1)))
__kernel void sha3(__global const uint8_t* inputs, __global uint64_t* hashes)
{
const uint32_t t = get_local_id(0);
if (t >= 25) {
return;
}
const uint32_t g = get_group_id(0);
const uint64_t input_offset = 10240 * 2 * g;
__global const uint64_t* input = (__global const uint64_t*)(inputs + input_offset);
__local uint64_t A[25];
__local uint64_t C[25];
A[t] = 0;
const uint32_t s = t % 5;
const int at = ppi[t][0];
const int ro0 = ppi[t][1];
const int ro1 = 64 - ro0;
const int c1 = c[t][0];
const int c2 = c[t][1];
const uint64_t k1 = (t == 0) ? 0xFFFFFFFFFFFFFFFFUL : 0UL;
const uint32_t input_size = 9973 * 2;
const uint32_t input_words = input_size / sizeof(uint64_t);
__global const uint64_t* const input_end17 = input + ((input_words / 17) * 17);
__global const uint64_t* const input_end = input + input_words;
for (; input < input_end17; input += 17) {
if (t < 17) A[t] ^= input[t];
ROUND(0x0000000000000001UL); ROUND(0x0000000000008082UL); ROUND(0x800000000000808AUL);
ROUND(0x8000000080008000UL); ROUND(0x000000000000808BUL); ROUND(0x0000000080000001UL);
ROUND(0x8000000080008081UL); ROUND(0x8000000000008009UL); ROUND(0x000000000000008AUL);
ROUND(0x0000000000000088UL); ROUND(0x0000000080008009UL); ROUND(0x000000008000000AUL);
ROUND(0x000000008000808BUL); ROUND(0x800000000000008BUL); ROUND(0x8000000000008089UL);
ROUND(0x8000000000008003UL); ROUND(0x8000000000008002UL); ROUND(0x8000000000000080UL);
ROUND(0x000000000000800AUL); ROUND(0x800000008000000AUL); ROUND(0x8000000080008081UL);
ROUND(0x8000000000008080UL); ROUND(0x0000000080000001UL); ROUND(0x8000000080008008UL);
}
const uint32_t wordIndex = input_end - input;
if (t < wordIndex) A[t] ^= input[t];
if (t == 0) {
uint64_t tail = 0;
__global const uint8_t* p = (__global const uint8_t*)input_end;
const uint32_t tail_size = input_size % sizeof(uint64_t);
for (uint32_t i = 0; i < tail_size; ++i) {
tail |= (uint64_t)(p[i]) << (i * 8);
}
A[wordIndex] ^= tail ^ ((uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8)));
A[16] ^= 0x8000000000000000UL;
}
barrier(CLK_LOCAL_MEM_FENCE);
#pragma unroll 1
for (int i = 0; i < ROUNDS; ++i) {
C[t] = A[s] ^ A[s + 5] ^ A[s + 10] ^ A[s + 15] ^ A[s + 20];
A[t] ^= C[s + 4] ^ R64(C[s + 1], 1, 63);
C[t] = R64(A[at], ro0, ro1);
A[t] = (C[t] ^ ((~C[c1]) & C[c2])) ^ (rc[i] & k1);
}
if (t < 4) {
hashes[g * 4 + t] = A[t];
}
}
__attribute__((reqd_work_group_size(32, 1, 1)))
__kernel void sha3_initial(__global const uint8_t* input_data, uint32_t input_size, uint32_t nonce, __global uint64_t* hashes)
{
const uint32_t t = get_local_id(0);
const uint32_t g = get_group_id(0);
if (t >= 25) {
return;
}
__global const uint64_t* input = (__global const uint64_t*)(input_data);
__local uint64_t A[25];
__local uint64_t C[25];
const uint32_t input_words = input_size / sizeof(uint64_t);
A[t] = (t < input_words) ? input[t] : 0;
if (t == 0) {
((__local uint32_t*)A)[11] = nonce + g;
const uint32_t tail_size = input_size % sizeof(uint64_t);
A[input_words] ^= (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8));
A[16] ^= 0x8000000000000000UL;
}
barrier(CLK_LOCAL_MEM_FENCE);
const uint32_t s = t % 5;
const int at = ppi[t][0];
const int ro0 = ppi[t][1];
const int ro1 = 64 - ro0;
const int c1 = c[t][0];
const int c2 = c[t][1];
const uint64_t k1 = (t == 0) ? (uint64_t)(-1) : 0;
ROUND(0x0000000000000001UL); ROUND(0x0000000000008082UL); ROUND(0x800000000000808AUL);
ROUND(0x8000000080008000UL); ROUND(0x000000000000808BUL); ROUND(0x0000000080000001UL);
ROUND(0x8000000080008081UL); ROUND(0x8000000000008009UL); ROUND(0x000000000000008AUL);
ROUND(0x0000000000000088UL); ROUND(0x0000000080008009UL); ROUND(0x000000008000000AUL);
ROUND(0x000000008000808BUL); ROUND(0x800000000000008BUL); ROUND(0x8000000000008089UL);
ROUND(0x8000000000008003UL); ROUND(0x8000000000008002UL); ROUND(0x8000000000000080UL);
ROUND(0x000000000000800AUL); ROUND(0x800000008000000AUL); ROUND(0x8000000080008081UL);
ROUND(0x8000000000008080UL); ROUND(0x0000000080000001UL); ROUND(0x8000000080008008UL);
if (t < 4) {
hashes[g * 4 + t] = A[t];
}
}
#undef ROUNDS
#undef R64
#undef ROUND

View file

@ -27,7 +27,6 @@
#define ALGO_AR2_CHUKWA 0x61130000
#define ALGO_AR2_CHUKWA_V2 0x61140000
#define ALGO_AR2_WRKZ 0x61120000
#define ALGO_ASTROBWT_DERO 0x41000000
#define ALGO_KAWPOW_RVN 0x6b0f0000
#define FAMILY_UNKNOWN 0
@ -38,5 +37,4 @@
#define FAMILY_CN_FEMTO 0x63110000
#define FAMILY_RANDOM_X 0x72000000
#define FAMILY_ARGON2 0x61000000
#define FAMILY_ASTROBWT 0x41000000
#define FAMILY_KAWPOW 0x6b000000

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,73 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/OclThreads.h"
#include "backend/opencl/wrappers/OclDevice.h"
#include "base/crypto/Algorithm.h"
#include "crypto/randomx/randomx.h"
#include "crypto/rx/RxAlgo.h"
namespace xmrig {
bool ocl_generic_astrobwt_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads)
{
if (algorithm.family() != Algorithm::ASTROBWT) {
return false;
}
if (algorithm.id() == Algorithm::ASTROBWT_DERO_2) {
uint32_t intensity = device.computeUnits() * 128;
if (!intensity || (intensity > 4096)) {
intensity = 4096;
}
threads.add(OclThread(device.index(), intensity, 1));
return true;
}
const size_t mem = device.globalMemSize();
uint32_t per_thread_mem = 10 << 20;
uint32_t intensity = static_cast<uint32_t>((mem - (128 << 20)) / per_thread_mem / 2);
intensity &= ~63U;
if (!intensity) {
return false;
}
if (intensity > 256) {
intensity = 256;
}
threads.add(OclThread(device.index(), intensity, 2));
return true;
}
} // namespace xmrig

View file

@ -1,42 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_FilterKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_FilterKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
enqueueNDRange(queue, 1, nullptr, &threads, &workgroup_size);
}
void xmrig::AstroBWT_FilterKernel::setArgs(uint32_t nonce, uint32_t bwt_max_size, cl_mem hashes, cl_mem filtered_hashes)
{
setArg(0, sizeof(uint32_t), &nonce);
setArg(1, sizeof(uint32_t), &bwt_max_size);
setArg(2, sizeof(cl_mem), &hashes);
setArg(3, sizeof(cl_mem), &filtered_hashes);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_FILTERKERNEL_H
#define XMRIG_ASTROBWT_FILTERKERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_FilterKernel : public OclKernel
{
public:
inline AstroBWT_FilterKernel(cl_program program) : OclKernel(program, "filter") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(uint32_t nonce, uint32_t bwt_max_size, cl_mem hashes, cl_mem filtered_hashes);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_FILTERKERNEL_H */

View file

@ -1,47 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_FindSharesKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_FindSharesKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
enqueueNDRange(queue, 1, nullptr, &threads, &workgroup_size);
}
void xmrig::AstroBWT_FindSharesKernel::setArgs(cl_mem hashes, cl_mem filtered_hashes, cl_mem shares)
{
setArg(0, sizeof(cl_mem), &hashes);
setArg(1, sizeof(cl_mem), &filtered_hashes);
setArg(3, sizeof(cl_mem), &shares);
}
void xmrig::AstroBWT_FindSharesKernel::setTarget(uint64_t target)
{
setArg(2, sizeof(uint64_t), &target);
}

View file

@ -1,49 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWTFINDSHARESKERNEL_H
#define XMRIG_ASTROBWTFINDSHARESKERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_FindSharesKernel : public OclKernel
{
public:
inline AstroBWT_FindSharesKernel(cl_program program) : OclKernel(program, "find_shares") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem hashes, cl_mem filtered_hashes, cl_mem shares);
void setTarget(uint64_t target);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWTFINDSHARESKERNEL_H */

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_MainKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_MainKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_MainKernel::setArgs(cl_mem inputs, cl_mem input_sizes, uint32_t input_stride, cl_mem indices, cl_mem tmp_indices)
{
setArg(0, sizeof(cl_mem), &inputs);
setArg(1, sizeof(cl_mem), &input_sizes);
setArg(2, sizeof(uint32_t), &input_stride);
setArg(3, sizeof(cl_mem), &indices);
setArg(4, sizeof(cl_mem), &tmp_indices);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_MAINKERNEL_H
#define XMRIG_ASTROBWT_MAINKERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_MainKernel : public OclKernel
{
public:
inline AstroBWT_MainKernel(cl_program program) : OclKernel(program, "BWT") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem inputs, cl_mem input_sizes, uint32_t input_stride, cl_mem indices, cl_mem tmp_indices);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_MAINKERNEL_H */

View file

@ -1,41 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_PrepareBatch2Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_PrepareBatch2Kernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
enqueueNDRange(queue, 1, nullptr, &threads, &workgroup_size);
}
void xmrig::AstroBWT_PrepareBatch2Kernel::setArgs(cl_mem hashes, cl_mem filtered_hashes, cl_mem bwt_data_sizes)
{
setArg(0, sizeof(cl_mem), &hashes);
setArg(1, sizeof(cl_mem), &filtered_hashes);
setArg(2, sizeof(cl_mem), &bwt_data_sizes);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_PREPAREBATCH2KERNEL_H
#define XMRIG_ASTROBWT_PREPAREBATCH2KERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_PrepareBatch2Kernel : public OclKernel
{
public:
inline AstroBWT_PrepareBatch2Kernel(cl_program program) : OclKernel(program, "prepare_batch2") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem hashes, cl_mem filtered_hashes, cl_mem bwt_data_sizes);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_PREPAREBATCH2KERNEL_H */

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_SHA3InitialKernel::enqueue(cl_command_queue queue, size_t threads)
{
const size_t workgroup_size = 32;
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_SHA3InitialKernel::setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys)
{
setArg(0, sizeof(cl_mem), &input);
setArg(1, sizeof(uint32_t), &input_size);
setArg(2, sizeof(uint32_t), &nonce);
setArg(3, sizeof(cl_mem), &output_salsa20_keys);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_SHA3INITIALKERNEL_H
#define XMRIG_ASTROBWT_SHA3INITIALKERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_SHA3InitialKernel : public OclKernel
{
public:
inline AstroBWT_SHA3InitialKernel(cl_program program) : OclKernel(program, "sha3_initial") {}
void enqueue(cl_command_queue queue, size_t threads);
void setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_SHA3INITIALKERNEL_H */

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_SHA3Kernel::enqueue(cl_command_queue queue, size_t threads)
{
const size_t workgroup_size = 32;
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_SHA3Kernel::setArgs(cl_mem inputs, cl_mem input_sizes, uint32_t input_stride, cl_mem output_salsa20_keys)
{
setArg(0, sizeof(cl_mem), &inputs);
setArg(1, sizeof(cl_mem), &input_sizes);
setArg(2, sizeof(uint32_t), &input_stride);
setArg(3, sizeof(cl_mem), &output_salsa20_keys);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_SHA3KERNEL_H
#define XMRIG_ASTROBWT_SHA3KERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_SHA3Kernel : public OclKernel
{
public:
inline AstroBWT_SHA3Kernel(cl_program program) : OclKernel(program, "sha3") {}
void enqueue(cl_command_queue queue, size_t threads);
void setArgs(cl_mem inputs, cl_mem input_sizes, uint32_t input_stride, cl_mem output_salsa20_keys);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_SHA3KERNEL_H */

View file

@ -1,43 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_Salsa20Kernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_Salsa20Kernel::setArgs(cl_mem salsa20_keys, cl_mem outputs, cl_mem output_sizes, uint32_t output_stride)
{
setArg(0, sizeof(cl_mem), &salsa20_keys);
setArg(1, sizeof(cl_mem), &outputs);
setArg(2, sizeof(cl_mem), &output_sizes);
setArg(3, sizeof(uint32_t), &output_stride);
}

View file

@ -1,48 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASTROBWT_SALSA20KERNEL_H
#define XMRIG_ASTROBWT_SALSA20KERNEL_H
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_Salsa20Kernel : public OclKernel
{
public:
inline AstroBWT_Salsa20Kernel(cl_program program) : OclKernel(program, "Salsa20_XORKeyStream") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem salsa20_keys, cl_mem outputs, cl_mem output_sizes, uint32_t output_stride);
};
} // namespace xmrig
#endif /* XMRIG_ASTROBWT_SALSA20KERNEL_H */

View file

@ -1,42 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_BWT_FixOrderKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_v2_BWT_FixOrderKernel::setArgs(cl_mem datas, cl_mem keys, cl_mem temp_storage)
{
setArg(0, sizeof(cl_mem), &datas);
setArg(1, sizeof(cl_mem), &keys);
setArg(2, sizeof(cl_mem), &temp_storage);
}

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_BWT_FixOrderKernel : public OclKernel
{
public:
inline AstroBWT_v2_BWT_FixOrderKernel(cl_program program) : OclKernel(program, "BWT_fix_order") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem datas, cl_mem keys, cl_mem temp_storage);
};
} // namespace xmrig

View file

@ -1,41 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_BWT_PreprocessKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_v2_BWT_PreprocessKernel::setArgs(cl_mem datas, cl_mem keys)
{
setArg(0, sizeof(cl_mem), &datas);
setArg(1, sizeof(cl_mem), &keys);
}

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_BWT_PreprocessKernel : public OclKernel
{
public:
inline AstroBWT_v2_BWT_PreprocessKernel(cl_program program) : OclKernel(program, "BWT_preprocess") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem datas, cl_mem keys);
};
} // namespace xmrig

View file

@ -1,46 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_FindSharesKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
enqueueNDRange(queue, 1, nullptr, &threads, &workgroup_size);
}
void xmrig::AstroBWT_v2_FindSharesKernel::setArgs(cl_mem hashes, cl_mem shares)
{
setArg(0, sizeof(cl_mem), &hashes);
setArg(2, sizeof(cl_mem), &shares);
}
void xmrig::AstroBWT_v2_FindSharesKernel::setTarget(uint64_t target)
{
setArg(1, sizeof(uint64_t), &target);
}

View file

@ -1,45 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_FindSharesKernel : public OclKernel
{
public:
inline AstroBWT_v2_FindSharesKernel(cl_program program) : OclKernel(program, "find_shares") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem hashes, cl_mem shares);
void setTarget(uint64_t target);
};
} // namespace xmrig

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_SHA3InitialKernel::enqueue(cl_command_queue queue, size_t threads)
{
const size_t workgroup_size = 32;
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_v2_SHA3InitialKernel::setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys)
{
setArg(0, sizeof(cl_mem), &input);
setArg(1, sizeof(uint32_t), &input_size);
setArg(2, sizeof(uint32_t), &nonce);
setArg(3, sizeof(cl_mem), &output_salsa20_keys);
}

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_SHA3InitialKernel : public OclKernel
{
public:
inline AstroBWT_v2_SHA3InitialKernel(cl_program program) : OclKernel(program, "sha3_initial") {}
void enqueue(cl_command_queue queue, size_t threads);
void setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys);
};
} // namespace xmrig

View file

@ -1,42 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_SHA3Kernel::enqueue(cl_command_queue queue, size_t threads)
{
const size_t workgroup_size = 32;
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_v2_SHA3Kernel::setArgs(cl_mem temp_storage, cl_mem hashes)
{
setArg(0, sizeof(cl_mem), &temp_storage);
setArg(1, sizeof(cl_mem), &hashes);
}

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_SHA3Kernel : public OclKernel
{
public:
inline AstroBWT_v2_SHA3Kernel(cl_program program) : OclKernel(program, "sha3") {}
void enqueue(cl_command_queue queue, size_t threads);
void setArgs(cl_mem temp_storage, cl_mem hashes);
};
} // namespace xmrig

View file

@ -1,41 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::AstroBWT_v2_Salsa20Kernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
{
const size_t gthreads = threads * workgroup_size;
enqueueNDRange(queue, 1, nullptr, &gthreads, &workgroup_size);
}
void xmrig::AstroBWT_v2_Salsa20Kernel::setArgs(cl_mem salsa20_keys, cl_mem outputs)
{
setArg(0, sizeof(cl_mem), &salsa20_keys);
setArg(1, sizeof(cl_mem), &outputs);
}

View file

@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "backend/opencl/wrappers/OclKernel.h"
namespace xmrig {
class AstroBWT_v2_Salsa20Kernel : public OclKernel
{
public:
inline AstroBWT_v2_Salsa20Kernel(cl_program program) : OclKernel(program, "Salsa20_XORKeyStream") {}
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
void setArgs(cl_mem salsa20_keys, cl_mem outputs);
};
} // namespace xmrig

View file

@ -110,45 +110,6 @@ if (WITH_OPENCL)
)
endif()
if (WITH_ASTROBWT)
list(APPEND HEADERS_BACKEND_OPENCL
src/backend/opencl/kernels/astrobwt/AstroBWT_FilterKernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_FindSharesKernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_MainKernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_PrepareBatch2Kernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.h
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h
src/backend/opencl/runners/OclAstroBWTRunner.h
src/backend/opencl/runners/OclAstroBWT_v2_Runner.h
)
list(APPEND SOURCES_BACKEND_OPENCL
src/backend/opencl/generators/ocl_generic_astrobwt_generator.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_FilterKernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_FindSharesKernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_MainKernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_PrepareBatch2Kernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.cpp
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.cpp
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.cpp
src/backend/opencl/runners/OclAstroBWTRunner.cpp
src/backend/opencl/runners/OclAstroBWT_v2_Runner.cpp
)
endif()
if (WITH_KAWPOW)
list(APPEND HEADERS_BACKEND_OPENCL
src/backend/opencl/kernels/kawpow/KawPow_CalculateDAGKernel.h

View file

@ -1,214 +0,0 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/runners/OclAstroBWTRunner.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_FilterKernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_FindSharesKernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_MainKernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_PrepareBatch2Kernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.h"
#include "backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.h"
#include "backend/opencl/OclLaunchData.h"
#include "backend/opencl/wrappers/OclLib.h"
#include "base/io/log/Log.h"
#include "base/net/stratum/Job.h"
namespace xmrig {
constexpr int STAGE1_SIZE = 147253;
constexpr uint32_t STAGE1_DATA_STRIDE = (STAGE1_SIZE + 256 + 255) & ~255U;
constexpr uint32_t OclAstroBWTRunner::BWT_DATA_STRIDE;
} // namespace xmrig
xmrig::OclAstroBWTRunner::OclAstroBWTRunner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
{
switch (data.device.type())
{
case OclDevice::Baffin:
case OclDevice::Ellesmere:
case OclDevice::Polaris:
case OclDevice::Lexa:
case OclDevice::Vega_10:
case OclDevice::Vega_20:
case OclDevice::Raven:
m_workgroup_size = 64;
break;
default:
m_workgroup_size = 32;
break;
}
m_options += " -DSALSA20_GROUP_SIZE=" + std::to_string(m_workgroup_size);
m_options += " -DBWT_GROUP_SIZE=" + std::to_string(m_workgroup_size);
m_bwt_allocation_size = static_cast<uint64_t>(m_intensity) * BWT_DATA_STRIDE;
m_batch_size1 = static_cast<uint32_t>(m_bwt_allocation_size / STAGE1_DATA_STRIDE + 255U) & ~255U;
m_bwt_allocation_size = std::max(m_bwt_allocation_size, m_batch_size1 * STAGE1_DATA_STRIDE);
m_bwt_data_sizes_host = new uint32_t[m_batch_size1];
}
xmrig::OclAstroBWTRunner::~OclAstroBWTRunner()
{
delete m_sha3_initial_kernel;
delete m_sha3_kernel;
delete m_salsa20_kernel;
delete m_bwt_kernel;
delete m_filter_kernel;
delete m_prepare_batch2_kernel;
delete m_find_shares_kernel;
OclLib::release(m_salsa20_keys);
OclLib::release(m_bwt_data);
OclLib::release(m_bwt_data_sizes);
OclLib::release(m_indices);
OclLib::release(m_tmp_indices);
OclLib::release(m_filtered_hashes);
delete [] m_bwt_data_sizes_host;
}
size_t xmrig::OclAstroBWTRunner::bufferSize() const
{
return OclBaseRunner::bufferSize() +
align(m_batch_size1 * 32) + // m_salsa20_keys
align(m_bwt_allocation_size) + // m_bwt_data
align(m_batch_size1 * 4) + // m_bwt_data_sizes
align(m_bwt_allocation_size * 8) + // m_indices
align(m_bwt_allocation_size * 8) + // m_tmp_indices
align((m_batch_size1 + m_intensity) * 36 + 4); // m_filtered_hashes
}
void xmrig::OclAstroBWTRunner::run(uint32_t nonce, uint32_t *hashOutput)
{
m_sha3_initial_kernel->setArg(2, sizeof(nonce), &nonce);
m_salsa20_kernel->setArg(3, sizeof(STAGE1_DATA_STRIDE), &STAGE1_DATA_STRIDE);
m_bwt_kernel->setArg(2, sizeof(STAGE1_DATA_STRIDE), &STAGE1_DATA_STRIDE);
const uint32_t t = STAGE1_DATA_STRIDE * 8;
m_sha3_kernel->setArg(2, sizeof(t), &t);
m_filter_kernel->setArg(0, sizeof(nonce), &nonce);
const uint32_t zero = 0;
enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero);
m_sha3_initial_kernel->enqueue(m_queue, m_batch_size1);
for (uint32_t i = 0; i < m_batch_size1; ++i) {
m_bwt_data_sizes_host[i] = STAGE1_SIZE;
}
enqueueWriteBuffer(m_bwt_data_sizes, CL_FALSE, 0, m_batch_size1 * sizeof(uint32_t), m_bwt_data_sizes_host);
m_salsa20_kernel->enqueue(m_queue, m_batch_size1, m_workgroup_size);
m_bwt_kernel->enqueue(m_queue, m_batch_size1, m_workgroup_size);
m_sha3_kernel->enqueue(m_queue, m_batch_size1);
m_filter_kernel->enqueue(m_queue, m_batch_size1, m_workgroup_size);
uint32_t num_filtered_hashes = 0;
enqueueReadBuffer(m_filtered_hashes, CL_TRUE, 0, sizeof(num_filtered_hashes), &num_filtered_hashes);
m_processedHashes = 0;
while (num_filtered_hashes >= m_intensity)
{
num_filtered_hashes -= m_intensity;
m_processedHashes += m_intensity;
m_salsa20_kernel->setArg(3, sizeof(BWT_DATA_STRIDE), &BWT_DATA_STRIDE);
m_bwt_kernel->setArg(2, sizeof(BWT_DATA_STRIDE), &BWT_DATA_STRIDE);
const uint32_t t = BWT_DATA_STRIDE * 8;
m_sha3_kernel->setArg(2, sizeof(t), &t);
m_prepare_batch2_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
m_salsa20_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
m_bwt_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
m_sha3_kernel->enqueue(m_queue, m_intensity);
m_find_shares_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
finalize(hashOutput);
OclLib::finish(m_queue);
}
}
void xmrig::OclAstroBWTRunner::set(const Job &job, uint8_t *blob)
{
if (job.size() > (Job::kMaxBlobSize - 4)) {
throw std::length_error("job size too big");
}
if (job.size() < Job::kMaxBlobSize) {
memset(blob + job.size(), 0, Job::kMaxBlobSize - job.size());
}
enqueueWriteBuffer(m_input, CL_TRUE, 0, Job::kMaxBlobSize, blob);
m_sha3_initial_kernel->setArgs(m_input, static_cast<uint32_t>(job.size()), *job.nonce(), m_salsa20_keys);
m_salsa20_kernel->setArgs(m_salsa20_keys, m_bwt_data, m_bwt_data_sizes, STAGE1_DATA_STRIDE);
m_bwt_kernel->setArgs(m_bwt_data, m_bwt_data_sizes, STAGE1_DATA_STRIDE, m_indices, m_tmp_indices);
m_sha3_kernel->setArgs(m_tmp_indices, m_bwt_data_sizes, STAGE1_DATA_STRIDE * 8, m_salsa20_keys);
m_filter_kernel->setArgs(*job.nonce(), BWT_DATA_MAX_SIZE, m_salsa20_keys, m_filtered_hashes);
m_prepare_batch2_kernel->setArgs(m_salsa20_keys, m_filtered_hashes, m_bwt_data_sizes);
m_find_shares_kernel->setArgs(m_salsa20_keys, m_filtered_hashes, m_output);
m_find_shares_kernel->setTarget(job.target());
const uint32_t zero = 0;
enqueueWriteBuffer(m_filtered_hashes, CL_TRUE, 0, sizeof(uint32_t), &zero);
}
void xmrig::OclAstroBWTRunner::build()
{
OclBaseRunner::build();
m_sha3_initial_kernel = new AstroBWT_SHA3InitialKernel(m_program);
m_sha3_kernel = new AstroBWT_SHA3Kernel(m_program);
m_salsa20_kernel = new AstroBWT_Salsa20Kernel(m_program);
m_bwt_kernel = new AstroBWT_MainKernel(m_program);
m_filter_kernel = new AstroBWT_FilterKernel(m_program);
m_prepare_batch2_kernel = new AstroBWT_PrepareBatch2Kernel(m_program);
m_find_shares_kernel = new AstroBWT_FindSharesKernel(m_program);
}
void xmrig::OclAstroBWTRunner::init()
{
OclBaseRunner::init();
const cl_mem_flags f = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
m_salsa20_keys = createSubBuffer(f, m_batch_size1 * 32);
m_bwt_data = createSubBuffer(f, m_bwt_allocation_size);
m_bwt_data_sizes = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_WRITE_ONLY, m_batch_size1 * 4);
m_indices = createSubBuffer(f, m_bwt_allocation_size * 8);
m_tmp_indices = createSubBuffer(f, m_bwt_allocation_size * 8);
m_filtered_hashes = createSubBuffer(CL_MEM_READ_WRITE, (m_batch_size1 + m_intensity) * 36 + 4);
}

View file

@ -1,89 +0,0 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_OCLASTROBWTRUNNER_H
#define XMRIG_OCLASTROBWTRUNNER_H
#include "backend/opencl/runners/OclBaseRunner.h"
namespace xmrig {
class AstroBWT_FilterKernel;
class AstroBWT_MainKernel;
class AstroBWT_PrepareBatch2Kernel;
class AstroBWT_Salsa20Kernel;
class AstroBWT_SHA3InitialKernel;
class AstroBWT_SHA3Kernel;
class AstroBWT_FindSharesKernel;
class OclAstroBWTRunner : public OclBaseRunner
{
public:
static constexpr uint32_t BWT_DATA_MAX_SIZE = 600 * 1024 - 256;
static constexpr uint32_t BWT_DATA_STRIDE = (BWT_DATA_MAX_SIZE + 256 + 255) & ~255U;
XMRIG_DISABLE_COPY_MOVE_DEFAULT(OclAstroBWTRunner)
OclAstroBWTRunner(size_t index, const OclLaunchData &data);
~OclAstroBWTRunner() override;
inline uint32_t roundSize() const override { return static_cast<uint32_t>(m_batch_size1); }
// ~0.5% of all hashes are invalid
inline uint32_t processedHashes() const override { return static_cast<uint32_t>(m_processedHashes * 0.995); }
protected:
size_t bufferSize() const override;
void run(uint32_t nonce, uint32_t *hashOutput) override;
void set(const Job &job, uint8_t *blob) override;
void build() override;
void init() override;
private:
AstroBWT_SHA3InitialKernel* m_sha3_initial_kernel = nullptr;
AstroBWT_SHA3Kernel* m_sha3_kernel = nullptr;
AstroBWT_Salsa20Kernel* m_salsa20_kernel = nullptr;
AstroBWT_MainKernel* m_bwt_kernel = nullptr;
AstroBWT_FilterKernel* m_filter_kernel = nullptr;
AstroBWT_PrepareBatch2Kernel* m_prepare_batch2_kernel = nullptr;
AstroBWT_FindSharesKernel* m_find_shares_kernel = nullptr;
cl_mem m_salsa20_keys = nullptr;
cl_mem m_bwt_data = nullptr;
cl_mem m_bwt_data_sizes = nullptr;
cl_mem m_indices = nullptr;
cl_mem m_tmp_indices = nullptr;
cl_mem m_filtered_hashes = nullptr;
uint32_t m_workgroup_size = 0;
uint64_t m_bwt_allocation_size = 0;
uint64_t m_batch_size1 = 0;
uint32_t m_processedHashes = 0;
uint32_t* m_bwt_data_sizes_host = nullptr;
};
} /* namespace xmrig */
#endif // XMRIG_OCLASTROBWTRUNNER_H

View file

@ -1,155 +0,0 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/runners/OclAstroBWT_v2_Runner.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h"
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h"
#include "backend/opencl/OclLaunchData.h"
#include "backend/opencl/wrappers/OclLib.h"
#include "base/io/log/Log.h"
#include "base/net/stratum/Job.h"
xmrig::OclAstroBWT_v2_Runner::OclAstroBWT_v2_Runner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
{
switch (data.device.type())
{
case OclDevice::Baffin:
case OclDevice::Ellesmere:
case OclDevice::Polaris:
case OclDevice::Lexa:
case OclDevice::Vega_10:
case OclDevice::Vega_20:
case OclDevice::Raven:
m_workgroup_size = 64;
break;
default:
m_workgroup_size = 32;
break;
}
m_options += " -DSALSA20_GROUP_SIZE=" + std::to_string(m_workgroup_size);
m_bwt_allocation_size = m_intensity * BWT_DATA_STRIDE;
}
xmrig::OclAstroBWT_v2_Runner::~OclAstroBWT_v2_Runner()
{
delete m_find_shares_kernel;
delete m_bwt_fix_order_kernel;
delete m_bwt_preprocess_kernel;
delete m_salsa20_kernel;
delete m_sha3_initial_kernel;
delete m_sha3_kernel;
OclLib::release(m_input);
OclLib::release(m_hashes);
OclLib::release(m_data);
OclLib::release(m_keys);
OclLib::release(m_temp_storage);
}
size_t xmrig::OclAstroBWT_v2_Runner::bufferSize() const
{
return OclBaseRunner::bufferSize() +
align(m_intensity * 32) + // m_hashes
align(m_bwt_allocation_size) + // m_data
align(m_bwt_allocation_size * 4) + // m_keys
align(m_bwt_allocation_size * 2); // m_temp_storage
}
void xmrig::OclAstroBWT_v2_Runner::run(uint32_t nonce, uint32_t *hashOutput)
{
const uint32_t zero = 0;
enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero);
m_sha3_initial_kernel->setArg(2, sizeof(nonce), &nonce);
m_sha3_initial_kernel->enqueue(m_queue, m_intensity);
m_salsa20_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
m_bwt_preprocess_kernel->enqueue(m_queue, m_intensity, 1024);
m_bwt_fix_order_kernel->enqueue(m_queue, m_intensity, 1024);
m_sha3_kernel->enqueue(m_queue, m_intensity);
m_find_shares_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
finalize(hashOutput);
OclLib::finish(m_queue);
for (uint32_t i = 0; i < hashOutput[0xFF]; ++i) {
hashOutput[i] += nonce;
}
}
void xmrig::OclAstroBWT_v2_Runner::set(const Job &job, uint8_t *blob)
{
if (job.size() > (Job::kMaxBlobSize - 4)) {
throw std::length_error("job size too big");
}
if (job.size() < Job::kMaxBlobSize) {
memset(blob + job.size(), 0, Job::kMaxBlobSize - job.size());
}
enqueueWriteBuffer(m_input, CL_TRUE, 0, Job::kMaxBlobSize, blob);
m_sha3_initial_kernel->setArgs(m_input, static_cast<uint32_t>(job.size()), *job.nonce(), m_hashes);
m_salsa20_kernel->setArgs(m_hashes, m_data);
m_bwt_preprocess_kernel->setArgs(m_data, m_keys);
m_bwt_fix_order_kernel->setArgs(m_data, m_keys, m_temp_storage);
m_sha3_kernel->setArgs(m_temp_storage, m_hashes);
m_find_shares_kernel->setArgs(m_hashes, m_output);
m_find_shares_kernel->setTarget(job.target());
}
void xmrig::OclAstroBWT_v2_Runner::build()
{
OclBaseRunner::build();
m_find_shares_kernel = new AstroBWT_v2_FindSharesKernel(m_program);
m_bwt_fix_order_kernel = new AstroBWT_v2_BWT_FixOrderKernel(m_program);
m_bwt_preprocess_kernel = new AstroBWT_v2_BWT_PreprocessKernel(m_program);
m_salsa20_kernel = new AstroBWT_v2_Salsa20Kernel(m_program);
m_sha3_initial_kernel = new AstroBWT_v2_SHA3InitialKernel(m_program);
m_sha3_kernel = new AstroBWT_v2_SHA3Kernel(m_program);
}
void xmrig::OclAstroBWT_v2_Runner::init()
{
OclBaseRunner::init();
const cl_mem_flags f = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
m_hashes = createSubBuffer(f, m_intensity * 32);
m_data = createSubBuffer(f, m_bwt_allocation_size);
m_keys = createSubBuffer(f, m_bwt_allocation_size * 4);
m_temp_storage = createSubBuffer(f, m_bwt_allocation_size * 2);
}

View file

@ -1,78 +0,0 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_OclAstroBWT_v2_Runner_H
#define XMRIG_OclAstroBWT_v2_Runner_H
#include "backend/opencl/runners/OclBaseRunner.h"
namespace xmrig {
class AstroBWT_v2_FindSharesKernel;
class AstroBWT_v2_BWT_FixOrderKernel;
class AstroBWT_v2_BWT_PreprocessKernel;
class AstroBWT_v2_Salsa20Kernel;
class AstroBWT_v2_SHA3InitialKernel;
class AstroBWT_v2_SHA3Kernel;
class OclAstroBWT_v2_Runner : public OclBaseRunner
{
public:
static constexpr uint32_t BWT_DATA_SIZE = 9973;
static constexpr uint32_t BWT_DATA_STRIDE = 10240;
XMRIG_DISABLE_COPY_MOVE_DEFAULT(OclAstroBWT_v2_Runner)
OclAstroBWT_v2_Runner(size_t index, const OclLaunchData &data);
~OclAstroBWT_v2_Runner() override;
inline uint32_t roundSize() const override { return m_intensity; }
inline uint32_t processedHashes() const override { return m_intensity; }
protected:
size_t bufferSize() const override;
void run(uint32_t nonce, uint32_t *hashOutput) override;
void set(const Job &job, uint8_t *blob) override;
void build() override;
void init() override;
private:
AstroBWT_v2_FindSharesKernel* m_find_shares_kernel = nullptr;
AstroBWT_v2_BWT_FixOrderKernel* m_bwt_fix_order_kernel = nullptr;
AstroBWT_v2_BWT_PreprocessKernel* m_bwt_preprocess_kernel = nullptr;
AstroBWT_v2_Salsa20Kernel* m_salsa20_kernel = nullptr;
AstroBWT_v2_SHA3InitialKernel* m_sha3_initial_kernel = nullptr;
AstroBWT_v2_SHA3Kernel* m_sha3_kernel = nullptr;
cl_mem m_hashes = nullptr;
cl_mem m_data = nullptr;
cl_mem m_keys = nullptr;
cl_mem m_temp_storage = nullptr;
uint32_t m_workgroup_size = 0;
uint32_t m_bwt_allocation_size = 0;
};
} /* namespace xmrig */
#endif // XMRIG_OclAstroBWT_v2_Runner_H

View file

@ -47,10 +47,6 @@ namespace xmrig {
extern bool ocl_generic_rx_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads);
#endif
#ifdef XMRIG_ALGO_ASTROBWT
extern bool ocl_generic_astrobwt_generator(const OclDevice& device, const Algorithm& algorithm, OclThreads& threads);
#endif
#ifdef XMRIG_ALGO_KAWPOW
extern bool ocl_generic_kawpow_generator(const OclDevice& device, const Algorithm& algorithm, OclThreads& threads);
#endif
@ -63,9 +59,6 @@ static ocl_gen_config_fun generators[] = {
# ifdef XMRIG_ALGO_RANDOMX
ocl_generic_rx_generator,
# endif
# ifdef XMRIG_ALGO_ASTROBWT
ocl_generic_astrobwt_generator,
# endif
# ifdef XMRIG_ALGO_KAWPOW
ocl_generic_kawpow_generator,
# endif

View file

@ -91,12 +91,6 @@ const char *Algorithm::kAR2_CHUKWA_V2 = "argon2/chukwav2";
const char *Algorithm::kAR2_WRKZ = "argon2/ninja";
#endif
#ifdef XMRIG_ALGO_ASTROBWT
const char *Algorithm::kASTROBWT = "astrobwt";
const char *Algorithm::kASTROBWT_DERO = "astrobwt";
const char *Algorithm::kASTROBWT_DERO_2 = "astrobwt/v2";
#endif
#ifdef XMRIG_ALGO_KAWPOW
const char *Algorithm::kKAWPOW = "kawpow";
const char *Algorithm::kKAWPOW_RVN = "kawpow";
@ -162,11 +156,6 @@ static const std::map<uint32_t, const char *> kAlgorithmNames = {
ALGO_NAME(AR2_WRKZ),
# endif
# ifdef XMRIG_ALGO_ASTROBWT
ALGO_NAME(ASTROBWT_DERO),
ALGO_NAME(ASTROBWT_DERO_2),
# endif
# ifdef XMRIG_ALGO_KAWPOW
ALGO_NAME(KAWPOW_RVN),
# endif
@ -282,13 +271,6 @@ static const std::map<const char *, Algorithm::Id, aliasCompare> kAlgorithmAlias
ALGO_ALIAS_AUTO(AR2_WRKZ), ALGO_ALIAS(AR2_WRKZ, "argon2/wrkz"),
# endif
# ifdef XMRIG_ALGO_ASTROBWT
ALGO_ALIAS_AUTO(ASTROBWT_DERO), ALGO_ALIAS(ASTROBWT_DERO, "astrobwt/dero"),
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/v2"),
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/dero_he"),
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/derohe"),
# endif
# ifdef XMRIG_ALGO_KAWPOW
ALGO_ALIAS_AUTO(KAWPOW_RVN), ALGO_ALIAS(KAWPOW_RVN, "kawpow/rvn"),
# endif
@ -370,7 +352,6 @@ std::vector<xmrig::Algorithm> xmrig::Algorithm::all(const std::function<bool(con
CN_UPX2,
RX_0, RX_WOW, RX_ARQ, RX_GRAFT, RX_SFX, RX_KEVA,
AR2_CHUKWA, AR2_CHUKWA_V2, AR2_WRKZ,
ASTROBWT_DERO, ASTROBWT_DERO_2,
KAWPOW_RVN,
GHOSTRIDER_RTM
};

View file

@ -81,8 +81,6 @@ public:
AR2_CHUKWA = 0x61130000, // "argon2/chukwa" Argon2id (Chukwa).
AR2_CHUKWA_V2 = 0x61140000, // "argon2/chukwav2" Argon2id (Chukwa v2).
AR2_WRKZ = 0x61120000, // "argon2/wrkz" Argon2id (WRKZ)
ASTROBWT_DERO = 0x41000000, // "astrobwt" AstroBWT (Dero)
ASTROBWT_DERO_2 = 0x41110000, // "astrobwt/v2" AstroBWT (Dero HE)
KAWPOW_RVN = 0x6b0f0000, // "kawpow/rvn" KawPow (RVN)
};
@ -96,7 +94,6 @@ public:
CN_FEMTO = 0x63110000,
RANDOM_X = 0x72000000,
ARGON2 = 0x61000000,
ASTROBWT = 0x41000000,
KAWPOW = 0x6b000000,
GHOSTRIDER = 0x6c000000
};
@ -156,12 +153,6 @@ public:
static const char *kAR2_WRKZ;
# endif
# ifdef XMRIG_ALGO_ASTROBWT
static const char *kASTROBWT;
static const char *kASTROBWT_DERO;
static const char* kASTROBWT_DERO_2;
# endif
# ifdef XMRIG_ALGO_KAWPOW
static const char *kKAWPOW;
static const char *kKAWPOW_RVN;
@ -194,14 +185,7 @@ public:
inline uint32_t minIntensity() const { return ((m_id == GHOSTRIDER_RTM) ? 8 : 1); };
inline uint32_t maxIntensity() const { return isCN() ? 5 : ((m_id == GHOSTRIDER_RTM) ? 8 : 1); };
inline size_t l3() const
{
# ifdef XMRIG_ALGO_ASTROBWT
return m_id != ASTROBWT_DERO ? l3(m_id) : 0x100000 * 20;
# else
return l3(m_id);
# endif
}
inline size_t l3() const { return l3(m_id); }
inline bool operator!=(Algorithm::Id id) const { return m_id != id; }
inline bool operator!=(const Algorithm &other) const { return !isEqual(other); }

View file

@ -49,8 +49,6 @@ static const CoinInfo coinInfo[] = {
{ Algorithm::RX_0, "XMR", "Monero", 120, 1000000000000, YELLOW_BG_BOLD( WHITE_BOLD_S " monero ") },
{ Algorithm::CN_R, "SUMO", "Sumokoin", 240, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " sumo ") },
{ Algorithm::RX_ARQ, "ARQ", "ArQmA", 120, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " arqma ") },
{ Algorithm::ASTROBWT_DERO, "DERO", "DERO", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero ") },
{ Algorithm::ASTROBWT_DERO_2, "DERO_HE", "DERO_HE", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero_he ") },
{ Algorithm::RX_GRAFT, "GRFT", "Graft", 120, 10000000000, BLUE_BG_BOLD( WHITE_BOLD_S " graft ") },
{ 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 ") },

View file

@ -35,8 +35,6 @@ public:
MONERO,
SUMO,
ARQMA,
DERO,
DERO_HE,
GRAFT,
KEVA,
RAVEN,

View file

@ -61,7 +61,6 @@ public:
virtual bool hasExtension(Extension extension) const noexcept = 0;
virtual bool isEnabled() const = 0;
virtual bool isTLS() const = 0;
virtual bool isWSS() const = 0;
virtual const char *mode() const = 0;
virtual const char *tag() const = 0;
virtual const char *tlsFingerprint() const = 0;

View file

@ -111,8 +111,6 @@ public:
CPUMaxThreadsKey = 1026,
MemoryPoolKey = 1027,
YieldKey = 1030,
AstroBWTMaxSizeKey = 1034,
AstroBWTAVX2Key = 1036,
Argon2ImplKey = 1039,
RandomXCacheQoSKey = 1040,

View file

@ -59,8 +59,6 @@ protected:
void setPool(const Pool &pool) override;
protected:
bool isWSS() const override { return false; }
enum SocketState {
UnconnectedState,
HostLookupState,

View file

@ -81,14 +81,6 @@ static constexpr size_t kZMQGreetingSize1 = 11;
static const char kZMQHandshake[] = "\4\x19\5READY\xbSocket-Type\0\0\0\3SUB";
static const char kZMQSubscribe[] = "\0\x18\1json-minimal-chain_main";
static const char kWSSLogin[] = "\
GET /ws/%s HTTP/1.1\r\n\
Host: %s\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Key: %s\r\n\
Sec-WebSocket-Version: 13\r\n\r\n";
} // namespace xmrig
@ -105,20 +97,11 @@ xmrig::DaemonClient::~DaemonClient()
{
delete m_timer;
delete m_ZMQSocket;
# ifdef XMRIG_FEATURE_TLS
delete m_wss.m_socket;
# endif
}
void xmrig::DaemonClient::deleteLater()
{
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS()) {
WSSClose(true);
}
else
# endif
if (m_pool.zmq_port() >= 0) {
ZMQClose(true);
}
@ -148,19 +131,13 @@ bool xmrig::DaemonClient::isTLS() const
}
bool xmrig::DaemonClient::isWSS() const
{
return m_pool.isWSS();
}
int64_t xmrig::DaemonClient::submit(const JobResult &result)
{
if (result.jobId != m_currentJobId) {
return -1;
}
char *data = (m_apiVersion == API_DERO) ? m_blockhashingblob.data() : m_blocktemplateStr.data();
char *data = m_blocktemplateStr.data();
const size_t sig_offset = m_job.nonceOffset() + m_job.nonceSize();
@ -182,17 +159,6 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
Cvt::toHex(data + m_job.nonceOffset() * 2, 8, reinterpret_cast<const uint8_t*>(&result.nonce), 4);
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS() && (m_apiVersion == API_DERO) && (m_pool.algorithm().id() == Algorithm::ASTROBWT_DERO_2)) {
char buf[256];
const int n = snprintf(buf, sizeof(buf), "{\"jobid\":\"%s\",\"mbl_blob\":\"%s\"}", m_job.id().data(), data);
if (0 <= n && n < static_cast<int>(sizeof(buf))) {
return WSSWrite(buf, n) ? 1 : -1;
}
return -1;
}
# endif
if (m_blocktemplate.hasMinerSignature()) {
Cvt::toHex(data + sig_offset * 2, 128, result.minerSignature(), 64);
}
@ -203,13 +169,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
Document doc(kObjectType);
Value params(kArrayType);
if (m_apiVersion == API_DERO) {
params.PushBack(m_blocktemplateStr.toJSON(), doc.GetAllocator());
params.PushBack(m_blockhashingblob.toJSON(), doc.GetAllocator());
}
else {
params.PushBack(m_blocktemplateStr.toJSON(), doc.GetAllocator());
}
params.PushBack(m_blocktemplateStr.toJSON(), doc.GetAllocator());
JsonRequest::create(doc, m_sequence, "submitblock", params);
@ -243,16 +203,11 @@ void xmrig::DaemonClient::connect()
m_pool.setAlgo(m_coin.algorithm());
}
const xmrig::Algorithm algo = m_pool.algorithm();
if ((algo == Algorithm::ASTROBWT_DERO) || (algo == Algorithm::ASTROBWT_DERO_2) || (m_coin == Coin::DERO) || (m_coin == Coin::DERO_HE)) {
m_apiVersion = API_DERO;
}
if ((m_apiVersion == API_MONERO) && !m_walletAddress.isValid()) {
return connectError("Invalid wallet address.");
}
if ((m_pool.zmq_port() >= 0) || m_pool.isWSS()) {
if (m_pool.zmq_port() >= 0) {
m_dns = Dns::resolve(m_pool.host(), this);
}
else {
@ -353,15 +308,7 @@ void xmrig::DaemonClient::onTimer(const Timer *)
connect();
}
else if (m_state == ConnectedState) {
if (m_pool.isWSS()) {
return;
}
if (m_apiVersion == API_DERO) {
rpcSend(JsonRequest::create(m_sequence, "get_info"));
}
else {
send((m_apiVersion == API_MONERO) ? kGetHeight : kGetInfo);
}
send((m_apiVersion == API_MONERO) ? kGetHeight : kGetInfo);
}
}
@ -396,14 +343,6 @@ void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, cons
uv_tcp_keepalive(s, 1, 60);
# endif
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS()) {
delete m_wss.m_socket;
m_wss.m_socket = s;
uv_tcp_connect(req, s, record.addr(m_pool.port()), onWSSConnect);
}
else
# endif
if (m_pool.zmq_port() > 0) {
delete m_ZMQSocket;
m_ZMQSocket = s;
@ -511,11 +450,6 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
# endif
}
if (m_apiVersion == API_DERO) {
const uint64_t offset = Json::getUint64(params, "reserved_offset");
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
}
if (m_coin.isValid()) {
job.setAlgorithm(m_coin.algorithm(m_blocktemplate.majorVersion()));
}
@ -536,13 +470,6 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
m_blocktemplateStr = std::move(blocktemplate);
m_prevHash = Json::getString(params, "prev_hash");
if (m_apiVersion == API_DERO) {
// Truncate to 32 bytes to have the same data as in get_info RPC
if (m_prevHash.size() > 64) {
m_prevHash.data()[64] = '\0';
}
}
if (m_state == ConnectingState) {
setState(ConnectedState);
}
@ -586,13 +513,6 @@ bool xmrig::DaemonClient::parseResponse(int64_t id, const rapidjson::Value &resu
const char* error_msg = nullptr;
if ((m_apiVersion == API_DERO) && result.HasMember("status")) {
error_msg = result["status"].GetString();
if (!error_msg || (strlen(error_msg) == 0) || (strcmp(error_msg, "OK") == 0)) {
error_msg = nullptr;
}
}
if (handleSubmitResponse(id, error_msg)) {
if (error_msg || (m_pool.zmq_port() < 0)) {
getBlockTemplate();
@ -613,12 +533,7 @@ int64_t xmrig::DaemonClient::getBlockTemplate()
Value params(kObjectType);
params.AddMember("wallet_address", m_user.toJSON(), allocator);
if (m_apiVersion == API_DERO) {
params.AddMember("reserve_size", static_cast<uint64_t>(kBlobReserveSize), allocator);
}
else {
params.AddMember("extra_nonce", Cvt::toHex(Cvt::randomBytes(kBlobReserveSize)).toJSON(doc), allocator);
}
params.AddMember("extra_nonce", Cvt::toHex(Cvt::randomBytes(kBlobReserveSize)).toJSON(doc), allocator);
JsonRequest::create(doc, m_sequence, "getblocktemplate", params);
@ -648,12 +563,6 @@ void xmrig::DaemonClient::retry()
setState(ConnectingState);
}
# ifdef XMRIG_FEATURE_TLS
if (m_wss.m_socket) {
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), onWSSClose);
}
else
# endif
if ((m_ZMQConnectionState != ZMQ_NOT_CONNECTED) && (m_ZMQConnectionState != ZMQ_DISCONNECTING)) {
uv_close(reinterpret_cast<uv_handle_t*>(m_ZMQSocket), onZMQClose);
}
@ -950,10 +859,14 @@ void xmrig::DaemonClient::ZMQParse()
m_ZMQRecvBuf.erase(m_ZMQRecvBuf.begin(), m_ZMQRecvBuf.begin() + (data - m_ZMQRecvBuf.data()));
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("tcp-zmq://%s:%u") BLACK_BOLD(" read ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.host().data(), m_pool.zmq_port(), msg.size(), msg.data());
msg.push_back('\0');
LOG_DEBUG(CYAN("tcp-zmq://%s:%u") BLACK_BOLD(" read ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.host().data(), m_pool.zmq_port(), msg.size() - 1, msg.data());
# endif
getBlockTemplate();
// Clear previous hash and check daemon height to guarantee that xmrig will call get_block_template RPC later
// We can't call get_block_template directly because daemon is not ready yet
m_prevHash = nullptr;
send(kGetHeight);
}
@ -978,377 +891,3 @@ bool xmrig::DaemonClient::ZMQClose(bool shutdown)
return false;
}
#ifdef XMRIG_FEATURE_TLS
void xmrig::DaemonClient::onWSSConnect(uv_connect_t* req, int status)
{
DaemonClient* client = getClient(req->data);
delete req;
if (!client) {
return;
}
if (status < 0) {
LOG_ERR("%s " RED("WSS connect error: ") RED_BOLD("\"%s\""), client->tag(), uv_strerror(status));
client->retry();
return;
}
client->WSSConnected();
}
void xmrig::DaemonClient::onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
DaemonClient* client = getClient(stream->data);
if (client) {
client->WSSRead(nread, buf);
}
NetBuffer::release(buf);
}
void xmrig::DaemonClient::onWSSClose(uv_handle_t* handle)
{
DaemonClient* client = getClient(handle->data);
if (client) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" disconnected"), client->m_pool.url().data());
# endif
client->m_wss.cleanup();
client->retry();
}
}
void xmrig::DaemonClient::onWSSShutdown(uv_handle_t* handle)
{
DaemonClient* client = getClient(handle->data);
if (client) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" shutdown"), client->m_pool.url().data());
# endif
client->m_wss.cleanup();
m_storage.remove(client->m_key);
}
}
void xmrig::DaemonClient::WSSConnected()
{
m_wss.m_ctx = SSL_CTX_new(SSLv23_method());
m_wss.m_write = BIO_new(BIO_s_mem());
m_wss.m_read = BIO_new(BIO_s_mem());
SSL_CTX_set_options(m_wss.m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
m_wss.m_ssl = SSL_new(m_wss.m_ctx);
SSL_set_connect_state(m_wss.m_ssl);
SSL_set_bio(m_wss.m_ssl, m_wss.m_read, m_wss.m_write);
SSL_do_handshake(m_wss.m_ssl);
if (WSSWrite(nullptr, 0)) {
uv_read_start(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), NetBuffer::onAlloc, onWSSRead);
}
}
bool xmrig::DaemonClient::WSSWrite(const char* data, size_t size)
{
if (!m_wss.m_socket) {
return false;
}
if (data && size) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" write ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), size, data);
# endif
if (!m_wss.m_handshake) {
WSS::Header h{};
h.fin = 1;
h.mask = 1;
h.opcode = 1;
uint8_t size_buf[8];
if (size < 126) {
h.payload_len = static_cast<uint8_t>(size);
}
else if (size < 65536) {
h.payload_len = 126;
size_buf[0] = static_cast<uint8_t>(size >> 8);
size_buf[1] = static_cast<uint8_t>(size & 0xFF);
}
else {
h.payload_len = 127;
uint64_t k = size;
for (int i = 7; i >= 0; --i, k >>= 8) {
size_buf[i] = static_cast<uint8_t>(k & 0xFF);
}
}
// Header
SSL_write(m_wss.m_ssl, &h, sizeof(h));
// Optional extended payload length
if (h.payload_len == 126) SSL_write(m_wss.m_ssl, size_buf, 2);
if (h.payload_len == 127) SSL_write(m_wss.m_ssl, size_buf, 8);
// Masking-key
SSL_write(m_wss.m_ssl, "\0\0\0\0", 4);
}
SSL_write(m_wss.m_ssl, data, static_cast<int>(size));
}
uv_buf_t buf;
buf.len = BIO_get_mem_data(m_wss.m_write, &buf.base);
if (buf.len == 0) {
return true;
}
const int rc = uv_try_write(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), &buf, 1);
BIO_reset(m_wss.m_write);
if (static_cast<size_t>(rc) == buf.len) {
return true;
}
LOG_ERR("%s " RED("WSS write failed, rc = %d"), tag(), rc);
WSSClose();
return false;
}
void xmrig::DaemonClient::WSSRead(ssize_t nread, const uv_buf_t* read_buf)
{
if (nread <= 0) {
LOG_ERR("%s " RED("WSS read failed, nread = %" PRId64), tag(), nread);
WSSClose();
return;
}
BIO_write(m_wss.m_read, read_buf->base, static_cast<int>(nread));
if (!SSL_is_init_finished(m_wss.m_ssl)) {
const int rc = SSL_connect(m_wss.m_ssl);
if ((rc < 0) && (SSL_get_error(m_wss.m_ssl, rc) == SSL_ERROR_WANT_READ)) {
WSSWrite(nullptr, 0);
}
else if (rc == 1) {
// login
static constexpr char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char key[25];
std::random_device r;
for (int i = 0; i < 21; ++i) {
key[i] = Base64[r() % 64];
}
key[21] = Base64[0];
key[22] = '=';
key[23] = '=';
key[24] = '\0';
const int n = snprintf(m_wss.m_buf, sizeof(m_wss.m_buf), kWSSLogin, m_pool.user().data(), m_pool.host().data(), key);
if (0 <= n && n < static_cast<int>(sizeof(m_wss.m_buf))) {
WSSWrite(m_wss.m_buf, n);
}
else {
WSSClose();
}
}
return;
}
int n = 0;
while ((n = SSL_read(m_wss.m_ssl, m_wss.m_buf, sizeof(m_wss.m_buf))) > 0) {
m_wss.m_data.insert(m_wss.m_data.end(), m_wss.m_buf, m_wss.m_buf + n);
// Skip the first message (HTTP upgrade response)
if (m_wss.m_handshake) {
const size_t len = m_wss.m_data.size();
if (len >= 4) {
for (size_t k = 0; k <= len - 4; ++k) {
if (memcmp(m_wss.m_data.data() + k, "\r\n\r\n", 4) == 0) {
m_wss.m_handshake = false;
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + k + 4);
break;
}
}
}
continue;
}
const uint8_t* p0 = reinterpret_cast<uint8_t*>(m_wss.m_data.data());
const uint8_t* p = p0;
const uint8_t* e = p0 + m_wss.m_data.size();
if (e - p < static_cast<int>(sizeof(WSS::Header)))
continue;
const WSS::Header* h = reinterpret_cast<const WSS::Header*>(p);
p += sizeof(WSS::Header);
uint64_t len = h->payload_len;
if (len == 126) {
if (e - p < static_cast<int>(sizeof(uint16_t))) {
continue;
}
len = 0;
for (size_t i = 0; i < sizeof(uint16_t); ++i, ++p) {
len = (len << 8) | *p;
}
}
else if (len == 127) {
if (e - p < static_cast<int>(sizeof(uint64_t))) {
continue;
}
len = 0;
for (size_t i = 0; i < sizeof(uint64_t); ++i, ++p) {
len = (len << 8) | *p;
}
}
uint8_t mask_key[4] = {};
if (h->mask) {
if (e - p < 4)
continue;
memcpy(mask_key, p, 4);
p += 4;
}
if (static_cast<uint64_t>(e - p) < len)
continue;
for (uint64_t i = 0; i < len; ++i) {
m_wss.m_message.push_back(p[i] ^ mask_key[i % 4]);
}
p += len;
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + (p - p0));
if (h->fin) {
if (m_wss.m_message.back() == '\n') {
m_wss.m_message.back() = '\0';
}
else {
m_wss.m_message.push_back('\0');
}
WSSParse();
m_wss.m_message.clear();
}
}
}
void xmrig::DaemonClient::WSSParse()
{
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" read ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), m_wss.m_message.size(), m_wss.m_message.data());
# endif
using namespace rapidjson;
Document doc;
if (doc.ParseInsitu(m_wss.m_message.data()).HasParseError() || !doc.IsObject()) {
if (!isQuiet()) {
LOG_ERR("%s " RED("JSON decode failed: ") RED_BOLD("\"%s\""), tag(), GetParseError_En(doc.GetParseError()));
}
return retry();
}
if (doc.HasMember(kLastError)) {
String err = Json::getString(doc, kLastError, "");
if (!err.isEmpty()) {
LOG_ERR("%s " RED_BOLD("\"%s\""), tag(), err.data());
return;
}
}
if (doc.HasMember(kBlockhashingBlob)) {
Job job(false, m_pool.algorithm(), String());
m_blockhashingblob = Json::getString(doc, kBlockhashingBlob, "");
if (m_blockhashingblob.isEmpty()) {
LOG_ERR("%s " RED_BOLD("blockhashing_blob is empty"), tag());
return;
}
job.setBlob(m_blockhashingblob);
memset(job.blob() + job.nonceOffset(), 0, job.nonceSize());
const uint64_t height = Json::getUint64(doc, kHeight);
job.setHeight(height);
job.setDiff(Json::getUint64(doc, "difficultyuint64"));
//job.setDiff(100000);
m_currentJobId = Json::getString(doc, "jobid");
job.setId(m_currentJobId);
m_job = std::move(job);
if (m_state == ConnectingState) {
setState(ConnectedState);
}
const uint64_t blocks = Json::getUint64(doc, "blocks");
const uint64_t miniblocks = Json::getUint64(doc, "miniblocks");
if ((blocks != m_wss.m_blocks) || (miniblocks != m_wss.m_miniblocks) || (height != m_wss.m_height)) {
LOG_INFO("%s " GREEN_BOLD("%" PRIu64 " blocks, %" PRIu64 " mini blocks"), tag(), blocks, miniblocks);
m_wss.m_blocks = blocks;
m_wss.m_miniblocks = miniblocks;
m_wss.m_height = height;
}
m_listener->onJobReceived(this, m_job, doc);
return;
}
}
bool xmrig::DaemonClient::WSSClose(bool shutdown)
{
if (m_wss.m_socket && (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_wss.m_socket)) == 0)) {
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), shutdown ? onWSSShutdown : onWSSClose);
return true;
}
return false;
}
void xmrig::DaemonClient::WSS::cleanup()
{
delete m_socket;
m_socket = nullptr;
if (m_ctx) {
SSL_CTX_free(m_ctx);
m_ctx = nullptr;
}
if (m_ssl) {
SSL_free(m_ssl);
m_ssl = nullptr;
}
m_read = nullptr;
m_write = nullptr;
m_handshake = true;
m_blocks = 0;
m_miniblocks = 0;
m_height = 0;
m_data.clear();
m_message.clear();
}
#endif

View file

@ -63,7 +63,6 @@ public:
protected:
bool disconnect() override;
bool isTLS() const override;
bool isWSS() const override;
int64_t submit(const JobResult &result) override;
void connect() override;
void connect(const Pool &pool) override;
@ -95,7 +94,6 @@ private:
enum {
API_CRYPTONOTE_DEFAULT,
API_MONERO,
API_DERO,
} m_apiVersion = API_MONERO;
BlockTemplate m_blocktemplate;
@ -143,45 +141,6 @@ private:
std::vector<char> m_ZMQSendBuf;
std::vector<char> m_ZMQRecvBuf;
# ifdef XMRIG_FEATURE_TLS
static void onWSSConnect(uv_connect_t* req, int status);
static void onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
static void onWSSClose(uv_handle_t* handle);
static void onWSSShutdown(uv_handle_t* handle);
void WSSConnected();
bool WSSWrite(const char* data, size_t size);
void WSSRead(ssize_t nread, const uv_buf_t* buf);
void WSSParse();
bool WSSClose(bool shutdown = false);
struct WSS {
struct Header
{
uint8_t opcode : 4;
uint8_t reserved : 3;
uint8_t fin : 1;
uint8_t payload_len : 7;
uint8_t mask : 1;
};
uv_tcp_t* m_socket = nullptr;
SSL_CTX* m_ctx = nullptr;
BIO* m_read = nullptr;
BIO* m_write = nullptr;
SSL* m_ssl = nullptr;
char m_buf[512] = {};
bool m_handshake = true;
uint64_t m_blocks = 0;
uint64_t m_miniblocks = 0;
uint64_t m_height = 0;
std::vector<char> m_data;
std::vector<char> m_message;
void cleanup();
} m_wss;
# endif
};

View file

@ -169,10 +169,6 @@ int32_t xmrig::Job::nonceOffset() const
auto f = algorithm().family();
if (f == Algorithm::KAWPOW) return 32;
if (f == Algorithm::GHOSTRIDER) return 76;
auto id = algorithm().id();
if (id == Algorithm::ASTROBWT_DERO_2) return 44;
return 39;
}

View file

@ -76,7 +76,6 @@ 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::kWSS = "wss";
const char *Pool::kUrl = "url";
const char *Pool::kUser = "user";
const char *Pool::kSpendSecretKey = "spend-secret-key";
@ -94,7 +93,7 @@ xmrig::Pool::Pool(const char *url) :
}
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, bool wss, Mode mode) :
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode) :
m_keepAlive(keepAlive),
m_mode(mode),
m_flags(1 << FLAG_ENABLED),
@ -106,7 +105,6 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
{
m_flags.set(FLAG_NICEHASH, nicehash || strstr(host, kNicehashHost));
m_flags.set(FLAG_TLS, tls);
m_flags.set(FLAG_WSS, wss);
}
@ -134,7 +132,6 @@ 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_WSS, Json::getBool(object, kWSS) || m_url.isWSS());
setKeepAlive(Json::getValue(object, kKeepalive));
@ -296,7 +293,6 @@ 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(kWSS), isWSS(), 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);

Some files were not shown because too many files have changed in this diff Show more