cn/r part 1 of 2.

This commit is contained in:
XMRig 2019-09-03 14:36:27 +07:00
parent 9b6ab55936
commit b9e15389ca
16 changed files with 1484 additions and 734 deletions

View file

@ -4,15 +4,12 @@
const fs = require('fs');
const path = require('path');
const { text2h, addIncludes } = require('./js/opencl');
const cwd = process.cwd();
const { text2h, text2h_bundle, addIncludes } = require('./js/opencl');
// const cwd = process.cwd();
function cn()
{
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/cn'));
const cn = addIncludes('cryptonight.cl', [
'algorithm.cl',
'wolf-aes.cl',
@ -30,4 +27,22 @@ function cn()
}
function cn_r()
{
const items = {};
items.cryptonight_r_defines_cl = addIncludes('cryptonight_r_defines.cl', [ 'wolf-aes.cl' ]);
items.cryptonight_r_cl = fs.readFileSync('cryptonight_r.cl', 'utf8');
// for (let key in items) {
// fs.writeFileSync(key + '_gen.cl', items[key]);
// }
fs.writeFileSync('cryptonight_r_cl.h', text2h_bundle('xmrig', items));
}
process.chdir(path.resolve('src/backend/opencl/cl/cn'));
cn();
cn_r();

View file

@ -24,11 +24,11 @@ function bin2h(buf, namespace, name)
}
function text2h(text, namespace, name)
function text2h_internal(text, name)
{
const buf = Buffer.from(text);
const size = buf.byteLength;
let out = `#pragma once\n\nnamespace ${namespace} {\n\nstatic char ${name}[${size + 1}] = {\n `;
let out = `\nstatic char ${name}[${size + 1}] = {\n `;
let b = 32;
for (let i = 0; i < size; i++) {
@ -42,12 +42,30 @@ function text2h(text, namespace, name)
out += '0x00';
out += `\n};\n\n} // namespace ${namespace}\n`;
out += '\n};\n';
return out;
}
function text2h(text, namespace, name)
{
return `#pragma once\n\nnamespace ${namespace} {\n` + text2h_internal(text, name) + `\n} // namespace ${namespace}\n`;
}
function text2h_bundle(namespace, items)
{
let out = `#pragma once\n\nnamespace ${namespace} {\n`;
for (let key in items) {
out += text2h_internal(items[key], key);
}
return out + `\n} // namespace ${namespace}\n`;
}
function addInclude(input, name)
{
return input.replace(`#include "${name}"`, fs.readFileSync(name, 'utf8'));
@ -66,7 +84,8 @@ function addIncludes(inputFileName, names)
}
module.exports.bin2h = bin2h;
module.exports.text2h = text2h;
module.exports.addInclude = addInclude;
module.exports.addIncludes = addIncludes;
module.exports.bin2h = bin2h;
module.exports.text2h = text2h;
module.exports.text2h_bundle = text2h_bundle;
module.exports.addInclude = addInclude;
module.exports.addIncludes = addIncludes;

View file

@ -488,8 +488,7 @@ __kernel void cn1(__global ulong *input, __global uint4 *Scratchpad, __global ul
uint sqrt_result = as_uint2(states[13]).s0;
#pragma unroll CN_UNROLL
for(int i = 0; i < ITERATIONS; ++i)
{
for (int i = 0; i < ITERATIONS; ++i) {
# ifdef __NV_CL_C_VERSION
uint idx = a[0] & 0x1FFFC0;
uint idx1 = a[0] & 0x30;

File diff suppressed because it is too large Load diff

View file

@ -1,175 +1,144 @@
R"===(
__attribute__((reqd_work_group_size(WORKSIZE, 1, 1)))
__kernel void cn1_cryptonight_r_N(__global uint4 *Scratchpad, __global ulong *states, uint variant, __global ulong *input, uint Threads)
__kernel void KERNEL_NAME(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, uint Threads)
{
ulong a[2], b[4];
__local uint AES0[256], AES1[256], AES2[256], AES3[256];
ulong a[2], b[4];
__local uint AES0[256], AES1[256], AES2[256], AES3[256];
const ulong gIdx = get_global_id(0) - get_global_offset(0);
const ulong gIdx = get_global_id(0) - get_global_offset(0);
for(int i = get_local_id(0); i < 256; i += WORKSIZE)
{
const uint tmp = AES0_C[i];
AES0[i] = tmp;
AES1[i] = rotate(tmp, 8U);
AES2[i] = rotate(tmp, 16U);
AES3[i] = rotate(tmp, 24U);
}
for(int i = get_local_id(0); i < 256; i += WORKSIZE) {
const uint tmp = AES0_C[i];
AES0[i] = tmp;
AES1[i] = rotate(tmp, 8U);
AES2[i] = rotate(tmp, 16U);
AES3[i] = rotate(tmp, 24U);
}
barrier(CLK_LOCAL_MEM_FENCE);
barrier(CLK_LOCAL_MEM_FENCE);
# if (COMP_MODE == 1)
// do not use early return here
if (gIdx < Threads)
{
states += 25 * gIdx;
# if defined(__NV_CL_C_VERSION)
Scratchpad += gIdx * (ITERATIONS >> 2);
# else
# if (STRIDED_INDEX == 0)
Scratchpad += gIdx * (MEMORY >> 4);
# elif (STRIDED_INDEX == 1)
Scratchpad += gIdx;
# elif (STRIDED_INDEX == 2)
Scratchpad += get_group_id(0) * (MEMORY >> 4) * WORKSIZE + MEM_CHUNK * get_local_id(0);
# endif
# endif
a[0] = states[0] ^ states[4];
a[1] = states[1] ^ states[5];
b[0] = states[2] ^ states[6];
b[1] = states[3] ^ states[7];
b[2] = states[8] ^ states[10];
b[3] = states[9] ^ states[11];
}
ulong2 bx0 = ((ulong2 *)b)[0];
ulong2 bx1 = ((ulong2 *)b)[1];
mem_fence(CLK_LOCAL_MEM_FENCE);
# ifdef __NV_CL_C_VERSION
__local uint16 scratchpad_line_buf[WORKSIZE];
__local uint16* scratchpad_line = scratchpad_line_buf + get_local_id(0);
# endif
{
states += 25 * gIdx;
# if defined(__NV_CL_C_VERSION)
Scratchpad += gIdx * (ITERATIONS >> 2);
# else
# if (STRIDED_INDEX == 0)
Scratchpad += gIdx * (MEMORY >> 4);
# elif (STRIDED_INDEX == 1)
Scratchpad += gIdx;
# elif (STRIDED_INDEX == 2)
Scratchpad += get_group_id(0) * (MEMORY >> 4) * WORKSIZE + MEM_CHUNK * get_local_id(0);
# endif
# endif
{
uint r0 = as_uint2(states[12]).s0;
uint r1 = as_uint2(states[12]).s1;
uint r2 = as_uint2(states[13]).s0;
uint r3 = as_uint2(states[13]).s1;
a[0] = states[0] ^ states[4];
a[1] = states[1] ^ states[5];
#pragma unroll CN_UNROLL
for (int i = 0; i < ITERATIONS; ++i) {
# ifdef __NV_CL_C_VERSION
uint idx = a[0] & 0x1FFFC0;
uint idx1 = a[0] & 0x30;
b[0] = states[2] ^ states[6];
b[1] = states[3] ^ states[7];
b[2] = states[8] ^ states[10];
b[3] = states[9] ^ states[11];
}
*scratchpad_line = *(__global uint16*)((__global uchar*)(Scratchpad) + idx);
# else
uint idx = a[0] & MASK;
# endif
ulong2 bx0 = ((ulong2 *)b)[0];
ulong2 bx1 = ((ulong2 *)b)[1];
uint4 c = SCRATCHPAD_CHUNK(0);
c = AES_Round(AES0, AES1, AES2, AES3, c, ((uint4 *)a)[0]);
mem_fence(CLK_LOCAL_MEM_FENCE);
{
const ulong2 chunk1 = as_ulong2(SCRATCHPAD_CHUNK(1));
const ulong2 chunk2 = as_ulong2(SCRATCHPAD_CHUNK(2));
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(3));
# ifdef __NV_CL_C_VERSION
__local uint16 scratchpad_line_buf[WORKSIZE];
__local uint16* scratchpad_line = scratchpad_line_buf + get_local_id(0);
# endif
c ^= as_uint4(chunk1) ^ as_uint4(chunk2) ^ as_uint4(chunk3);
# if (COMP_MODE == 1)
// do not use early return here
if (gIdx < Threads)
# endif
{
uint r0 = as_uint2(states[12]).s0;
uint r1 = as_uint2(states[12]).s1;
uint r2 = as_uint2(states[13]).s0;
uint r3 = as_uint2(states[13]).s1;
SCRATCHPAD_CHUNK(1) = as_uint4(chunk3 + bx1);
SCRATCHPAD_CHUNK(2) = as_uint4(chunk1 + bx0);
SCRATCHPAD_CHUNK(3) = as_uint4(chunk2 + ((ulong2 *)a)[0]);
}
#pragma unroll CN_UNROLL
for(int i = 0; i < ITERATIONS; ++i)
{
# ifdef __NV_CL_C_VERSION
uint idx = a[0] & 0x1FFFC0;
uint idx1 = a[0] & 0x30;
SCRATCHPAD_CHUNK(0) = as_uint4(bx0) ^ c;
*scratchpad_line = *(__global uint16*)((__global uchar*)(Scratchpad) + idx);
# else
uint idx = a[0] & MASK;
# endif
# ifdef __NV_CL_C_VERSION
*(__global uint16*)((__global uchar*)(Scratchpad) + idx) = *scratchpad_line;
uint4 c = SCRATCHPAD_CHUNK(0);
c = AES_Round(AES0, AES1, AES2, AES3, c, ((uint4 *)a)[0]);
idx = as_ulong2(c).s0 & 0x1FFFC0;
idx1 = as_ulong2(c).s0 & 0x30;
{
const ulong2 chunk1 = as_ulong2(SCRATCHPAD_CHUNK(1));
const ulong2 chunk2 = as_ulong2(SCRATCHPAD_CHUNK(2));
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(3));
*scratchpad_line = *(__global uint16*)((__global uchar*)(Scratchpad) + idx);
# else
idx = as_ulong2(c).s0 & MASK;
# endif
#if (VARIANT == VARIANT_4)
c ^= as_uint4(chunk1) ^ as_uint4(chunk2) ^ as_uint4(chunk3);
#endif
uint4 tmp = SCRATCHPAD_CHUNK(0);
SCRATCHPAD_CHUNK(1) = as_uint4(chunk3 + bx1);
SCRATCHPAD_CHUNK(2) = as_uint4(chunk1 + bx0);
SCRATCHPAD_CHUNK(3) = as_uint4(chunk2 + ((ulong2 *)a)[0]);
}
tmp.s0 ^= r0 + r1;
tmp.s1 ^= r2 + r3;
const uint r4 = as_uint2(a[0]).s0;
const uint r5 = as_uint2(a[1]).s0;
const uint r6 = as_uint4(bx0).s0;
const uint r7 = as_uint4(bx1).s0;
const uint r8 = as_uint4(bx1).s2;
SCRATCHPAD_CHUNK(0) = as_uint4(bx0) ^ c;
XMRIG_INCLUDE_RANDOM_MATH
# ifdef __NV_CL_C_VERSION
*(__global uint16*)((__global uchar*)(Scratchpad) + idx) = *scratchpad_line;
const uint2 al = (uint2)(as_uint2(a[0]).s0 ^ r2, as_uint2(a[0]).s1 ^ r3);
const uint2 ah = (uint2)(as_uint2(a[1]).s0 ^ r0, as_uint2(a[1]).s1 ^ r1);
idx = as_ulong2(c).s0 & 0x1FFFC0;
idx1 = as_ulong2(c).s0 & 0x30;
ulong2 t;
t.s0 = mul_hi(as_ulong2(c).s0, as_ulong2(tmp).s0);
t.s1 = as_ulong2(c).s0 * as_ulong2(tmp).s0;
{
const ulong2 chunk1 = as_ulong2(SCRATCHPAD_CHUNK(1));
const ulong2 chunk2 = as_ulong2(SCRATCHPAD_CHUNK(2));
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(3));
*scratchpad_line = *(__global uint16*)((__global uchar*)(Scratchpad) + idx);
# else
idx = as_ulong2(c).s0 & MASK;
# endif
c ^= as_uint4(chunk1) ^ as_uint4(chunk2) ^ as_uint4(chunk3);
uint4 tmp = SCRATCHPAD_CHUNK(0);
SCRATCHPAD_CHUNK(1) = as_uint4(chunk3 + bx1);
SCRATCHPAD_CHUNK(2) = as_uint4(chunk1 + bx0);
SCRATCHPAD_CHUNK(3) = as_uint4(chunk2 + ((ulong2 *)a)[0]);
}
tmp.s0 ^= r0 + r1;
tmp.s1 ^= r2 + r3;
const uint r4 = as_uint2(a[0]).s0;
const uint r5 = as_uint2(a[1]).s0;
const uint r6 = as_uint4(bx0).s0;
const uint r7 = as_uint4(bx1).s0;
#if (VARIANT == VARIANT_4)
const uint r8 = as_uint4(bx1).s2;
#endif
a[1] = as_ulong(ah) + t.s1;
a[0] = as_ulong(al) + t.s0;
XMRIG_INCLUDE_RANDOM_MATH
SCRATCHPAD_CHUNK(0) = ((uint4 *)a)[0];
#if (VARIANT == VARIANT_4)
const uint2 al = (uint2)(as_uint2(a[0]).s0 ^ r2, as_uint2(a[0]).s1 ^ r3);
const uint2 ah = (uint2)(as_uint2(a[1]).s0 ^ r0, as_uint2(a[1]).s1 ^ r1);
#endif
# ifdef __NV_CL_C_VERSION
*(__global uint16*)((__global uchar*)(Scratchpad) + idx) = *scratchpad_line;
# endif
ulong2 t;
t.s0 = mul_hi(as_ulong2(c).s0, as_ulong2(tmp).s0);
t.s1 = as_ulong2(c).s0 * as_ulong2(tmp).s0;
{
const ulong2 chunk1 = as_ulong2(SCRATCHPAD_CHUNK(1))
#if (VARIANT == VARIANT_WOW)
^ t
#endif
;
const ulong2 chunk2 = as_ulong2(SCRATCHPAD_CHUNK(2));
#if (VARIANT == VARIANT_WOW)
t ^= chunk2;
#endif
const ulong2 chunk3 = as_ulong2(SCRATCHPAD_CHUNK(3));
((uint4 *)a)[0] ^= tmp;
bx1 = bx0;
bx0 = as_ulong2(c);
}
}
#if (VARIANT == VARIANT_4)
c ^= as_uint4(chunk1) ^ as_uint4(chunk2) ^ as_uint4(chunk3);
#endif
SCRATCHPAD_CHUNK(1) = as_uint4(chunk3 + bx1);
SCRATCHPAD_CHUNK(2) = as_uint4(chunk1 + bx0);
SCRATCHPAD_CHUNK(3) = as_uint4(chunk2 + ((ulong2 *)a)[0]);
}
#if (VARIANT == VARIANT_4)
a[1] = as_ulong(ah) + t.s1;
a[0] = as_ulong(al) + t.s0;
#else
a[1] += t.s1;
a[0] += t.s0;
#endif
SCRATCHPAD_CHUNK(0) = ((uint4 *)a)[0];
# ifdef __NV_CL_C_VERSION
*(__global uint16*)((__global uchar*)(Scratchpad) + idx) = *scratchpad_line;
# endif
((uint4 *)a)[0] ^= tmp;
bx1 = bx0;
bx0 = as_ulong2(c);
}
}
mem_fence(CLK_GLOBAL_MEM_FENCE);
mem_fence(CLK_GLOBAL_MEM_FENCE);
}
)==="

View file

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

View file

@ -1,4 +1,3 @@
R"===(
#ifdef __NV_CL_C_VERSION
# define SCRATCHPAD_CHUNK(N) (*(__local uint4*)((__local uchar*)(scratchpad_line) + (idx1 ^ (N << 4))))
#else
@ -12,9 +11,6 @@ R"===(
#endif
#define ROT_BITS 32
#define VARIANT_WOW 12
#define VARIANT_4 13
#define MEM_CHUNK (1 << MEM_CHUNK_EXPONENT)
)==="
#include "wolf-aes.cl"

View file

@ -35,6 +35,7 @@ typedef struct _cl_context *cl_context;
namespace xmrig {
class Algorithm;
class Job;
class OclLaunchData;
@ -48,6 +49,7 @@ public:
virtual bool selfTest() const = 0;
virtual bool set(const Job &job, uint8_t *blob) = 0;
virtual cl_context ctx() const = 0;
virtual const Algorithm &algorithm() const = 0;
virtual const char *buildOptions() const = 0;
virtual const char *deviceKey() const = 0;
virtual const char *source() const = 0;

View file

@ -23,15 +23,26 @@
*/
#include <string>
#include "backend/opencl/kernels/Cn1Kernel.h"
#include "backend/opencl/wrappers/OclLib.h"
xmrig::Cn1Kernel::Cn1Kernel(cl_program program) : OclKernel(program, "cn1")
xmrig::Cn1Kernel::Cn1Kernel(cl_program program)
: OclKernel(program, "cn1")
{
}
xmrig::Cn1Kernel::Cn1Kernel(cl_program program, uint64_t height)
: OclKernel(program, ("cn1_" + std::to_string(height)).c_str())
{
}
bool xmrig::Cn1Kernel::enqueue(cl_command_queue queue, uint32_t nonce, size_t threads, size_t worksize)
{
const size_t offset = nonce;

View file

@ -36,6 +36,7 @@ class Cn1Kernel : public OclKernel
{
public:
Cn1Kernel(cl_program program);
Cn1Kernel(cl_program program, uint64_t height);
bool enqueue(cl_command_queue queue, uint32_t nonce, size_t threads, size_t worksize);
bool setArgs(cl_mem input, cl_mem scratchpads, cl_mem states, uint32_t threads);
};

View file

@ -19,6 +19,7 @@ if (WITH_OPENCL)
src/backend/opencl/OclWorker.h
src/backend/opencl/runners/OclBaseRunner.h
src/backend/opencl/runners/OclCnRunner.h
src/backend/opencl/runners/tools/OclCnR.h
src/backend/opencl/wrappers/OclContext.h
src/backend/opencl/wrappers/OclDevice.h
src/backend/opencl/wrappers/OclError.h
@ -43,6 +44,7 @@ if (WITH_OPENCL)
src/backend/opencl/OclWorker.cpp
src/backend/opencl/runners/OclBaseRunner.cpp
src/backend/opencl/runners/OclCnRunner.cpp
src/backend/opencl/runners/tools/OclCnR.cpp
src/backend/opencl/wrappers/OclContext.cpp
src/backend/opencl/wrappers/OclDevice.cpp
src/backend/opencl/wrappers/OclError.cpp

View file

@ -48,6 +48,7 @@ public:
protected:
inline cl_context ctx() const override { return m_ctx; }
inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const char *buildOptions() const override { return m_options.c_str(); }
inline const char *deviceKey() const override { return m_deviceKey.c_str(); }
inline const char *source() const override { return m_source; }

View file

@ -29,6 +29,7 @@
#include "backend/opencl/kernels/CnBranchKernel.h"
#include "backend/opencl/OclLaunchData.h"
#include "backend/opencl/runners/OclCnRunner.h"
#include "backend/opencl/runners/tools/OclCnR.h"
#include "backend/opencl/wrappers/OclLib.h"
#include "base/io/log/Log.h"
#include "base/net/stratum/Job.h"
@ -169,9 +170,15 @@ bool xmrig::OclCnRunner::run(uint32_t nonce, uint32_t *hashOutput)
bool xmrig::OclCnRunner::selfTest() const
{
return OclBaseRunner::selfTest() &&
m_cn0->isValid() &&
m_cn1->isValid() && m_cn2->isValid();
if (OclBaseRunner::selfTest() && m_cn0->isValid() && m_cn2->isValid()) {
if (m_algorithm != Algorithm::CN_R) {
return m_cn1->isValid();
}
return true;
}
return false;
}
@ -194,6 +201,13 @@ bool xmrig::OclCnRunner::set(const Job &job, uint8_t *blob)
return false;
}
if (m_algorithm == Algorithm::CN_R && m_height != job.height()) {
delete m_cn1;
m_height = job.height();
m_cn1 = new Cn1Kernel(OclCnR::get(*this, m_height), m_height);
}
if (!m_cn1->setArgs(m_input, m_scratchpads, m_states, intensity)) {
return false;
}
@ -221,9 +235,12 @@ void xmrig::OclCnRunner::build()
}
m_cn0 = new Cn0Kernel(m_program);
m_cn1 = new Cn1Kernel(m_program);
m_cn2 = new Cn2Kernel(m_program);
if (m_algorithm != Algorithm::CN_R) {
m_cn1 = new Cn1Kernel(m_program);
}
for (size_t i = 0; i < BRANCH_MAX; ++i) {
m_branchKernels[i] = new CnBranchKernel(i, m_program);
}

View file

@ -66,6 +66,7 @@ private:
Cn0Kernel *m_cn0 = nullptr;
Cn1Kernel *m_cn1 = nullptr;
Cn2Kernel *m_cn2 = nullptr;
uint64_t m_height = 0;
std::vector<cl_mem> m_branches = { nullptr, nullptr, nullptr, nullptr };
std::vector<CnBranchKernel *> m_branchKernels = { nullptr, nullptr, nullptr, nullptr };

View file

@ -0,0 +1,178 @@
/* 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 <cstring>
#include <mutex>
#include <regex>
#include <sstream>
#include <string>
#include <thread>
#include "backend/opencl/cl/cn/cryptonight_r_cl.h"
#include "backend/opencl/interfaces/IOclRunner.h"
#include "backend/opencl/OclCache.h"
#include "backend/opencl/OclLaunchData.h"
#include "backend/opencl/OclThread.h"
#include "backend/opencl/runners/tools/OclCnR.h"
#include "backend/opencl/wrappers/OclError.h"
#include "backend/opencl/wrappers/OclLib.h"
#include "base/io/log/Log.h"
#include "base/tools/Chrono.h"
#include "crypto/cn/CryptoNight_monero.h"
namespace xmrig {
static std::string getCode(const V4_Instruction *code, int code_size)
{
std::stringstream s;
for (int i = 0; i < code_size; ++i) {
const V4_Instruction inst = code[i];
const uint32_t a = inst.dst_index;
const uint32_t b = inst.src_index;
switch (inst.opcode)
{
case MUL:
s << 'r' << a << "*=r" << b << ';';
break;
case ADD:
s << 'r' << a << "+=r" << b << '+' << inst.C << "U;";
break;
case SUB:
s << 'r' << a << "-=r" << b << ';';
break;
case ROR:
case ROL:
s << 'r' << a << "=rotate(r" << a << ((inst.opcode == ROR) ? ",ROT_BITS-r" : ",r") << b << ");";
break;
case XOR:
s << 'r' << a << "^=r" << b << ';';
break;
}
s << '\n';
}
return s.str();
}
class CacheEntry
{
public:
inline CacheEntry(const Algorithm &algorithm, uint64_t heightOffset, uint32_t deviceIndex, cl_program program) :
algorithm(algorithm),
program(program),
deviceIndex(deviceIndex),
heightOffset(heightOffset)
{}
const Algorithm algorithm;
const cl_program program;
const uint32_t deviceIndex;
const uint64_t heightOffset;
};
static std::mutex mutex;
static std::vector<CacheEntry> cache;
static cl_program search(const Algorithm &algorithm, uint64_t offset, uint32_t index)
{
std::lock_guard<std::mutex> lock(mutex);
for (const CacheEntry &entry : cache) {
if (entry.heightOffset == offset && entry.deviceIndex == index && entry.algorithm == algorithm) {
return entry.program;
}
}
return nullptr;
}
static inline cl_program search(const IOclRunner &runner, uint64_t offset) { return search(runner.algorithm(), offset, runner.data().thread.index()); }
cl_program build(const IOclRunner &runner, const std::string &source, uint64_t offset)
{
std::lock_guard<std::mutex> lock(mutex);
cl_int ret;
cl_device_id device = runner.data().device.id();
const char *s = source.c_str();
cl_program program = OclLib::createProgramWithSource(runner.ctx(), 1, &s, nullptr, &ret);
if (ret != CL_SUCCESS) {
return nullptr;
}
if (OclLib::buildProgram(program, 1, &device, runner.buildOptions()) != CL_SUCCESS) {
printf("BUILD LOG:\n%s\n", OclLib::getProgramBuildLog(program, device).data());
OclLib::releaseProgram(program);
return nullptr;
}
cache.emplace_back(runner.algorithm(), offset, runner.data().thread.index(), program);
return program;
}
} // namespace xmrig
cl_program xmrig::OclCnR::get(const IOclRunner &runner, uint64_t height, bool background)
{
const uint64_t offset = (height / kHeightChunkSize) * kHeightChunkSize;
cl_program program = search(runner, offset);
if (program) {
return program;
}
std::string source(cryptonight_r_defines_cl);
for (size_t i = 0; i < kHeightChunkSize; ++i) {
V4_Instruction code[256];
const int code_size = v4_random_math_init<Algorithm::CN_R>(code, offset + i);
const std::string kernel = std::regex_replace(cryptonight_r_cl, std::regex("XMRIG_INCLUDE_RANDOM_MATH"), getCode(code, code_size));
source += std::regex_replace(kernel, std::regex("KERNEL_NAME"), "cn1_" + std::to_string(offset + i));
}
return build(runner, source, offset);;
}

View file

@ -0,0 +1,55 @@
/* 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_OCLCNR_H
#define XMRIG_OCLCNR_H
#include <stdint.h>
typedef struct _cl_program *cl_program;
namespace xmrig {
class Algorithm;
class IOclRunner;
class OclCnR
{
public:
constexpr static size_t kPrecompilationDepth = 1;
constexpr static size_t kHeightChunkSize = 10;
static cl_program get(const IOclRunner &runner, uint64_t height, bool background = false);
};
} // namespace xmrig
#endif /* XMRIG_OCLCNR_H */