diff --git a/CMakeLists.txt b/CMakeLists.txt index 392920e8..8e5b846a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -478,12 +478,17 @@ if(LOVR_ENABLE_MATH) target_sources(lovr PRIVATE src/math/math.c src/math/curve.c + src/math/pool.c src/math/randomGenerator.c src/math/transform.c src/api/math.c src/api/types/curve.c + src/api/types/pool.c src/api/types/randomGenerator.c src/api/types/transform.c + src/api/types/vec3.c + src/api/types/quat.c + src/api/types/mat4.c src/lib/noise1234/noise1234.c ) diff --git a/src/api.h b/src/api.h index 73f66f84..22fee4bd 100644 --- a/src/api.h +++ b/src/api.h @@ -37,11 +37,14 @@ extern const luaL_Reg lovrDistanceJoint[]; extern const luaL_Reg lovrFont[]; extern const luaL_Reg lovrHingeJoint[]; extern const luaL_Reg lovrJoint[]; +extern const luaL_Reg lovrMat4[]; extern const luaL_Reg lovrMaterial[]; extern const luaL_Reg lovrMesh[]; extern const luaL_Reg lovrMicrophone[]; extern const luaL_Reg lovrModel[]; extern const luaL_Reg lovrModelData[]; +extern const luaL_Reg lovrPool[]; +extern const luaL_Reg lovrQuat[]; extern const luaL_Reg lovrRandomGenerator[]; extern const luaL_Reg lovrRasterizer[]; extern const luaL_Reg lovrShader[]; @@ -55,9 +58,12 @@ extern const luaL_Reg lovrTexture[]; extern const luaL_Reg lovrTextureData[]; extern const luaL_Reg lovrThread[]; extern const luaL_Reg lovrTransform[]; +extern const luaL_Reg lovrVec3[]; extern const luaL_Reg lovrVertexData[]; extern const luaL_Reg lovrWorld[]; +extern const luaL_Reg lovrLightUserdata[]; + // Enums extern const char* ArcModes[]; extern const char* AttributeTypes[]; diff --git a/src/api/math.c b/src/api/math.c index 45d6ff0e..46a6258b 100644 --- a/src/api/math.c +++ b/src/api/math.c @@ -1,10 +1,65 @@ #include "api.h" #include "api/math.h" +#include "api/math.lua.h" #include "math/math.h" #include "math/curve.h" +#include "math/pool.h" #include "math/randomGenerator.h" #include "math/transform.h" +static const char* lovrMathTypeNames[] = { + [MATH_VEC3] = "vec3", + [MATH_QUAT] = "quat", + [MATH_MAT4] = "mat4" +}; + +static const luaL_Reg* lovrMathTypes[] = { + [MATH_VEC3] = lovrVec3, + [MATH_QUAT] = lovrQuat, + [MATH_MAT4] = lovrMat4 +}; + +static int lovrMathTypeRefs[MAX_MATH_TYPES]; + +float* luax_tolightmathtype(lua_State* L, int index, MathType* type) { + uintptr_t p = (uintptr_t) lua_touserdata(L, index), aligned = ALIGN(p, POOL_ALIGN); + return *type = p - aligned, p ? (float*) aligned : NULL; +} + +void luax_pushlightmathtype(lua_State* L, float* p, MathType type) { + lua_pushlightuserdata(L, (uint8_t*) p + type); +} + +float* luax_tomathtype(lua_State* L, int index, MathType* type) { + int luaType = lua_type(L, index); + if (luaType == LUA_TLIGHTUSERDATA) { + return luax_tolightmathtype(L, index, type); + } else if (luaType == LUA_TUSERDATA && lua_getmetatable(L, index)) { + lua_pushliteral(L, "_type"); + lua_rawget(L, -2); + *type = lua_tointeger(L, -1); + lua_pop(L, 2); + return lua_touserdata(L, index); + } else if (luaType > LUA_TTHREAD) { // cdata + lua_getfield(L, index, "_type"); + *type = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, index, "_p"); + float* p = *(float**) lua_topointer(L, index); + lua_pop(L, 1); + return p; + } + return NULL; +} + +float* luax_checkmathtype(lua_State* L, int index, MathType type, const char* expected) { + MathType t; + float* p = luax_tomathtype(L, index, &t); + if (!p || t != type) luaL_typerror(L, index, expected ? expected : lovrMathTypeNames[type]); + return p; +} + static int l_lovrMathNewCurve(lua_State* L) { int top = lua_gettop(L); bool table = lua_type(L, 1) == LUA_TTABLE; @@ -43,6 +98,14 @@ static int l_lovrMathNewCurve(lua_State* L) { return 1; } +static int l_lovrMathNewPool(lua_State* L) { + size_t size = luaL_optinteger(L, 1, DEFAULT_POOL_SIZE); + Pool* pool = lovrPoolCreate(size); + luax_pushobject(L, pool); + lovrRelease(pool); + return 1; +} + static int l_lovrMathNewRandomGenerator(lua_State* L) { RandomGenerator* generator = lovrRandomGeneratorCreate(); if (lua_gettop(L) > 0){ @@ -162,8 +225,33 @@ static int l_lovrMathLinearToGamma(lua_State* L) { } } +static int l_lovrMathVec3(lua_State* L) { + luax_pushobject(L, lovrMathGetPool()); + lua_insert(L, 1); + return l_lovrPoolVec3(L); +} + +static int l_lovrMathQuat(lua_State* L) { + luax_pushobject(L, lovrMathGetPool()); + lua_insert(L, 1); + return l_lovrPoolQuat(L); +} + +static int l_lovrMathMat4(lua_State* L) { + luax_pushobject(L, lovrMathGetPool()); + lua_insert(L, 1); + return l_lovrPoolMat4(L); +} + +static int l_lovrMathDrain(lua_State* L) { + luax_pushobject(L, lovrMathGetPool()); + lua_insert(L, 1); + return l_lovrPoolDrain(L); +} + static const luaL_Reg lovrMath[] = { { "newCurve", l_lovrMathNewCurve }, + { "newPool", l_lovrMathNewPool }, { "newRandomGenerator", l_lovrMathNewRandomGenerator }, { "newTransform", l_lovrMathNewTransform }, { "orientationToDirection", l_lovrMathOrientationToDirection }, @@ -175,17 +263,101 @@ static const luaL_Reg lovrMath[] = { { "setRandomSeed", l_lovrMathSetRandomSeed }, { "gammaToLinear", l_lovrMathGammaToLinear }, { "linearToGamma", l_lovrMathLinearToGamma }, + { "vec3", l_lovrMathVec3 }, + { "quat", l_lovrMathQuat }, + { "mat4", l_lovrMathMat4 }, + { "drain", l_lovrMathDrain }, { NULL, NULL } }; +static int l_lovrLightUserdata__index(lua_State* L) { + MathType type; + luax_tolightmathtype(L, 1, &type); + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrMathTypeRefs[type]); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + return 1; +} + +static int l_lovrLightUserdataOp(lua_State* L) { + MathType type; + luax_tolightmathtype(L, 1, &type); + lua_rawgeti(L, LUA_REGISTRYINDEX, lovrMathTypeRefs[type]); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_gettable(L, -2); + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + lua_call(L, 2, 1); + return 1; +} + int luaopen_lovr_math(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrMath); luax_registertype(L, "Curve", lovrCurve); + luax_registertype(L, "Pool", lovrPool); luax_registertype(L, "RandomGenerator", lovrRandomGenerator); luax_registertype(L, "Transform", lovrTransform); - if (lovrMathInit()) { + + // Store every math type metatable in the registry and register it as a type + for (int i = 0; i < MAX_MATH_TYPES; i++) { + lua_newtable(L); + luaL_register(L, NULL, lovrMathTypes[i]); + lovrMathTypeRefs[i] = luaL_ref(L, LUA_REGISTRYINDEX); + + luaL_newmetatable(L, lovrMathTypeNames[i]); + lua_pushvalue(L, -1); + lua_setfield(L, -1, "__index"); + lua_pushinteger(L, i); + lua_setfield(L, -2, "_type"); + luaL_register(L, NULL, lovrMathTypes[i]); + lua_pop(L, 1); + } + + // Global lightuserdata metatable + lua_pushlightuserdata(L, NULL); + lua_newtable(L); + + lua_pushcfunction(L, l_lovrLightUserdata__index); + lua_setfield(L, -2, "__index"); + + const char* ops[] = { "__add", "__sub", "__mul", "__div", "__unm", "__len", "__tostring" }; + for (size_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) { + lua_pushstring(L, ops[i]); + lua_pushcclosure(L, l_lovrLightUserdataOp, 1); + lua_setfield(L, -2, ops[i]); + } + + lua_setmetatable(L, -2); + lua_pop(L, 1); + + // Pool size + luax_pushconf(L); + lua_getfield(L, -1, "math"); + size_t poolSize = DEFAULT_POOL_SIZE; + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "poolsize"); + if (lua_isnumber(L, -1)) { + poolSize = lua_tonumber(L, -1); + } + lua_pop(L, 1); + } + lua_pop(L, 2); + + // Module + if (lovrMathInit(poolSize)) { luax_atexit(L, lovrMathDestroy); } + + // Inject LuaJIT superjuice + lua_pushcfunction(L, luax_getstack); + lovrAssert(!luaL_loadbuffer(L, (const char*) math_lua, math_lua_len, "math.lua"), "Could not load math.lua"); + lua_pushvalue(L, -3); // lovr.math + luaL_getmetatable(L, "Pool"); + if (lua_pcall(L, 2, 0, -4)) { + lovrThrow(lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 1; } diff --git a/src/api/math.h b/src/api/math.h index a74e1863..a3e3c5e4 100644 --- a/src/api/math.h +++ b/src/api/math.h @@ -1,10 +1,21 @@ #include "lib/math.h" +#include "math/pool.h" #include "math/randomGenerator.h" +float* luax_tolightmathtype(lua_State* L, int index, MathType* type); +void luax_pushlightmathtype(lua_State* L, float* p, MathType type); +float* luax_tomathtype(lua_State* L, int index, MathType* type); +float* luax_checkmathtype(lua_State* L, int index, MathType type, const char* message); int luax_readtransform(lua_State* L, int index, mat4 transform, int scaleComponents); Seed luax_checkrandomseed(lua_State* L, int index); int l_lovrRandomGeneratorRandom(lua_State* L); int l_lovrRandomGeneratorRandomNormal(lua_State* L); int l_lovrRandomGeneratorGetSeed(lua_State* L); int l_lovrRandomGeneratorSetSeed(lua_State* L); - +int l_lovrPoolVec3(lua_State* L); +int l_lovrPoolQuat(lua_State* L); +int l_lovrPoolMat4(lua_State* L); +int l_lovrPoolDrain(lua_State* L); +int l_lovrVec3Set(lua_State* L); +int l_lovrQuatSet(lua_State* L); +int l_lovrMat4Set(lua_State* L); diff --git a/src/api/math.lua b/src/api/math.lua new file mode 100644 index 00000000..61f80cc7 --- /dev/null +++ b/src/api/math.lua @@ -0,0 +1,377 @@ +local _Gmath = math +local math, Pool = ... +local ffi = type(jit) == 'table' and jit.status() and require 'ffi' +if not ffi then return end + +local C, new, cast, typeof, istype = ffi.C, ffi.new, ffi.cast, ffi.typeof, ffi.istype + +ffi.cdef [[ + typedef union { struct { float x; float y; float z; }; float _p[4]; } vec3; + typedef union { struct { float x; float y; float z; float w; }; float _p[4]; } quat; + typedef union { struct { float m[16]; }; float _p[16]; } mat4; + + // From math/pool.h + typedef struct Pool Pool; + enum { MATH_VEC3, MATH_QUAT, MATH_MAT4 }; + + Pool* lovrPoolCreate(size_t count); + vec3* lovrPoolAllocateVec3(Pool* pool); + quat* lovrPoolAllocateQuat(Pool* pool); + mat4* lovrPoolAllocateMat4(Pool* pool); + + Pool* lovrMathGetPool(); + + // From lib/math.h + // Careful, the declarations below are using as the structs above, not the usual C types + + vec3* vec3_init(vec3* v, vec3* u); + vec3* vec3_set(vec3* v, float x, float y, float z); + vec3* vec3_add(vec3* v, vec3* u); + vec3* vec3_scale(vec3* v, float s); + vec3* vec3_normalize(vec3* v); + float vec3_length(vec3* v); + float vec3_dot(vec3* v, vec3* u); + vec3* vec3_cross(vec3* v, vec3* u); + vec3* vec3_lerp(vec3* v, vec3* u, float t); + + quat* quat_init(quat* q, quat* r); + quat* quat_set(quat* q, float x, float y, float z, float w); + quat* quat_fromAngleAxis(quat* q, float angle, float ax, float ay, float az); + quat* quat_fromMat4(quat* q, mat4* m); + quat* quat_mul(quat* q, quat* r); + quat* quat_normalize(quat* q); + float quat_length(quat* q); + quat* quat_slerp(quat* q, quat* r, float t); + void quat_rotate(quat* q, vec3* v); + void quat_getAngleAxis(quat* q, float* angle, float* x, float* y, float* z); + quat* quat_between(quat* q, vec3* u, vec3* v); + + mat4* mat4_set(mat4* m, mat4* n); + mat4* mat4_identity(mat4* m); + mat4* mat4_invert(mat4* m); + mat4* mat4_transpose(mat4* m); + mat4* mat4_multiply(mat4* m, mat4* n); + mat4* mat4_translate(mat4* m, float x, float y, float z); + mat4* mat4_rotate(mat4* m, float angle, float x, float y, float z); + mat4* mat4_rotateQuat(mat4* m, quat* q); + mat4* mat4_scale(mat4* m, float x, float y, float z); + void mat4_getPose(mat4* m, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az); + void mat4_getTransform(mat4* m, float* x, float* y, float* z, float* sx, float* sy, float* sz, float* angle, float* ax, float* ay, float* az); + mat4* mat4_setTransform(mat4* m, float x, float y, float z, float sx, float sy, float sz, float angle, float ax, float ay, float az); + mat4* mat4_orthographic(mat4* m, float left, float right, float top, float bottom, float near, float far); + mat4* mat4_perspective(mat4* m, float near, float far, float fov, float aspect); + mat4* mat4_lookAt(mat4* m, vec3* from, vec3* to, vec3* up); + void mat4_transform(mat4* m, float* x, float* y, float* z); + void mat4_transformDirection(mat4* m, float* x, float* y, float* z); +]] + +function Pool:vec3(...) return C.lovrPoolAllocateVec3(cast('Pool**', self)[0]):set(...) end +function Pool:quat(...) return C.lovrPoolAllocateQuat(cast('Pool**', self)[0]):set(...) end +function Pool:mat4(...) return C.lovrPoolAllocateMat4(cast('Pool**', self)[0]):set(...) end + +local pool = C.lovrMathGetPool() +function math.vec3(...) return C.lovrPoolAllocateVec3(pool):set(...) end +function math.quat(...) return C.lovrPoolAllocateQuat(pool):set(...) end +function math.mat4(...) return C.lovrPoolAllocateMat4(pool):set(...) end + +local vec3 = ffi.typeof('vec3') +local quat = ffi.typeof('quat') +local mat4 = ffi.typeof('mat4') + +local function checktype(t, name) + return function(x, i, exp) + if not istype(t, x) then + local fn, arg, exp = debug.getinfo(2, 'n').name, i and ('argument #' .. i) or 'self', exp or name + error(string.format('Bad %s to %s (%s expected, got %s)', arg, fn, exp, type(x)), 3) + end + end +end + +local checkvec3 = checktype(vec3, 'vec3') +local checkquat = checktype(quat, 'quat') +local checkmat4 = checktype(mat4, 'mat4') + +ffi.metatype(vec3, { + __index = { + _type = C.MATH_VEC3, + + unpack = function(v) + checkvec3(v) + return v.x, v.y, v.z + end, + + set = function(v, x, y, z) + checkvec3(v) + if type(x) == 'number' then + C.vec3_set(v, x, y, z) + else + checkvec3(x, 1) + C.vec3_init(v, x) + end + return v + end, + + copy = function(v, u) + checkvec3(v) + if istype(vec3, u) then + return u:set(v) + else + return math.vec3(v) + end + end, + + save = function(v) + checkvec3(v) + return vec3(v:unpack()) + end, + + normalize = function(v) + checkvec3(v) + C.vec3_normalize(v) + return v + end, + + dot = function(v, u) + checkvec3(v) + checkvec3(u) + --return C.vec3_dot(v, u) + return v.x * u.x + v.y * u.y + v.z * u.z + end, + + cross = function(v, u) + checkvec3(v) + checkvec3(u) + C.vec3_cross(v, u) + return v + end, + + lerp = function(v, u, t) + checkvec3(v) + checkvec3(u) + C.vec3_lerp(v, u, t) + return v + end + }, + + __add = function(v, u) return math.vec3(v.x + u.x, v.y + u.y, v.z + u.z) end, + __sub = function(v, u) return math.vec3(v.x - u.x, v.y - u.y, v.z - u.z) end, + __mul = function(v, u) return math.vec3(v.x * u.x, v.y * u.y, v.z * u.z) end, + __div = function(v, u) return math.vec3(v.x / u.x, v.y / u.y, v.z / u.z) end, + __unm = function(v) return math.vec3(-v.x, -v.y, -v.z) end, + __len = function(v) return C.vec3_length(v) end, + __tostring = function(v) return string.format('(%f, %f, %f)', v.x, v.y, v.z) end +}) + +ffi.metatype(quat, { + __index = { + unpack = function(q, raw) + checkquat(q) + if raw then + return q.x, q.y, q.z, q.w + else + local f = new('float[4]') + C.quat_getAngleAxis(q, f + 0, f + 1, f + 2, f + 3) + return f[0], f[1], f[2], f[3] + end + end, + + set = function(q, x, y, z, w, raw) + checkquat(q) + if type(x) == 'number' then + if type(y) == 'number' then + if raw then + C.quat_set(q, x, y, z, w) + else + local axis = new('vec3[1]') + axis[0] = vec3(y, z, w) + C.quat_fromAngleAxis(q, x, axis) + end + else + local axis = checkvec3(y) + -- + end + elseif istype(vec3, x) then + if istype(vec3, y) then + -- + else + -- + end + elseif istype(quat, x) then + C.quat_init(q, x) + elseif istype(mat4, x) then + C.quat_fromMat4(q, x) + else + error('Expected a vec3, quat, mat4, or number') + end + return q + end, + + copy = function(q, r) + if istype(quat, r) then + return r:set(q) + else + return math.quat(q) + end + end, + + save = function(q) + checkquat(q) + return quat(quat, q:unpack()) + end, + + normalize = function(q) + checkquat(q) + C.quat_normalize(q) + end, + + slerp = function(q, r, t) + checkquat(q) + checkquat(r) + C.quat_slerp(q, r, t) + end + }, + + __mul = function(q, r) + checkquat(q) + if istype(vec3, r) then + local v = math.vec3(r) + C.quat_rotate(q, v) + return v + else + checkquat(r, 'Expected a vec3 or quat') + local out = math.quat() + C.quat_mul(C.quat_init(out, q), r) + return out + end + end, + + __len = function(q) + checkquat(q) + return C.quat_length(q) + end, + + __tostring = function(q) return string.format('(%f, %f, %f, %f)', q.x, q.y, q.z, q.w) end +}) + +ffi.metatype(mat4, { + __index = { + unpack = function(m) + checkmat4(m) + return -- yum + m.m[0], m.m[1], m.m[2], m.m[3], + m.m[4], m.m[5], m.m[6], m.m[7], + m.m[8], m.m[9], m.m[10], m.m[11], + m.m[12], m.m[13], m.m[14], m.m[15] + end, + + set = function(m, ...) + checkmat4(m) + if ... then + m.m[0], m.m[1], m.m[2], m.m[3], + m.m[4], m.m[5], m.m[6], m.m[7], + m.m[8], m.m[9], m.m[10], m.m[11], + m.m[12], m.m[13], m.m[14], m.m[15] = ... + else + m:identity() + end + return m + end, + + copy = function(m) + checkmat4(m) + return math.mat4(m:unpack()) + end, + + save = function(m) + checkmat4(m) + return mat4(m:unpack()) + end, + + identity = function(m) + checkmat4(m) + C.mat4_identity(m) + end, + + inverse = function(m) + checkmat4(m) + local out = math.mat4() + C.mat4_invert(C.mat4_set(out, m)) + return out + end, + + transpose = function(m) + checkmat4(m) + local out = math.mat4() + C.mat4_transpose(C.mat4_set(out, m)) + return out + end, + + translate = function(m, x, y, z) + checkmat4(m) + if type(x) == 'number' then + C.mat4_translate(m, x, y, z) + else + checkvec3(x, 1, 'vec3 or number') + C.mat4_translate(m, x.x, x.y, x.z) + end + end, + + rotate = function(m, angle, ax, ay, az) + checkmat4(m) + if type(angle) == 'number' then + C.mat4_rotate(m, angle, ax, ay, az) + else + checkquat(angle, 1, 'quat or number') + C.mat4_rotateQuat(m, angle) + end + end, + + scale = function(m, sx, sy, sz) + checkmat4(m) + if type(sx) == 'number' then + C.mat4_scale(m, sx, sy, sz) + else + checkvec3(sx, 1, 'vec3 or number') + C.mat4_scale(m, sx.x, sx.y, sx.z) + end + end, + + getTransform = function(m) + checkmat4(m) + -- + end, + + setTransform = function(m) + checkmat4(m) + -- + end, + + perspective = function(m) + checkmat4(m) + -- + end, + + orthographic = function(m) + checkmat4(m) + -- + end, + + lookAt = function(m) + -- + end + }, + + __mul = function(m, n) + checkmat4(m) + if istype(mat4, n) then + local out = math.mat4(m) + C.mat4_multiply(out, n) + return out + else + checkvec3(n, 1, 'mat4 or vec3') + local f = new('float[3]', n.x, n.y, n.z) + C.mat4_transform(m, f + 0, f + 1, f + 2) + return math.vec3(f[0], f[1], f[2]) + end + end +}) diff --git a/src/api/math.lua.h b/src/api/math.lua.h new file mode 100644 index 00000000..253d5814 --- /dev/null +++ b/src/api/math.lua.h @@ -0,0 +1,842 @@ +unsigned char math_lua[] = { + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x47, 0x6d, 0x61, 0x74, 0x68, + 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x0a, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2c, 0x20, 0x50, 0x6f, 0x6f, 0x6c, + 0x20, 0x3d, 0x20, 0x2e, 0x2e, 0x2e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x66, 0x66, 0x69, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x6a, 0x69, 0x74, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6a, 0x69, 0x74, 0x2e, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x28, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x20, 0x27, 0x66, 0x66, + 0x69, 0x27, 0x0a, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x66, + 0x69, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x43, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x2c, 0x20, 0x63, 0x61, 0x73, + 0x74, 0x2c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x2c, 0x20, 0x69, + 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x66, 0x69, 0x2e, + 0x43, 0x2c, 0x20, 0x66, 0x66, 0x69, 0x2e, 0x6e, 0x65, 0x77, 0x2c, 0x20, + 0x66, 0x66, 0x69, 0x2e, 0x63, 0x61, 0x73, 0x74, 0x2c, 0x20, 0x66, 0x66, + 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x2c, 0x20, 0x66, 0x66, + 0x69, 0x2e, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x66, 0x66, + 0x69, 0x2e, 0x63, 0x64, 0x65, 0x66, 0x20, 0x5b, 0x5b, 0x0a, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x75, 0x6e, 0x69, 0x6f, + 0x6e, 0x20, 0x7b, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x3b, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x79, 0x3b, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x7a, 0x3b, 0x20, 0x7d, 0x3b, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x5f, 0x70, 0x5b, 0x34, 0x5d, 0x3b, 0x20, 0x7d, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x20, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x20, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x78, 0x3b, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x79, 0x3b, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x7a, 0x3b, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x77, 0x3b, 0x20, 0x7d, 0x3b, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x5f, 0x70, 0x5b, 0x34, 0x5d, 0x3b, 0x20, 0x7d, + 0x20, 0x71, 0x75, 0x61, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x20, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x20, 0x7b, + 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x6d, 0x5b, 0x31, 0x36, 0x5d, 0x3b, 0x20, 0x7d, + 0x3b, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x5f, 0x70, 0x5b, 0x31, + 0x36, 0x5d, 0x3b, 0x20, 0x7d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x3b, 0x0a, + 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x6d, + 0x61, 0x74, 0x68, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x68, 0x0a, 0x20, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x20, 0x50, 0x6f, 0x6f, 0x6c, 0x20, 0x50, 0x6f, 0x6f, + 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x7b, 0x20, + 0x4d, 0x41, 0x54, 0x48, 0x5f, 0x56, 0x45, 0x43, 0x33, 0x2c, 0x20, 0x4d, + 0x41, 0x54, 0x48, 0x5f, 0x51, 0x55, 0x41, 0x54, 0x2c, 0x20, 0x4d, 0x41, + 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x34, 0x20, 0x7d, 0x3b, 0x0a, 0x0a, + 0x20, 0x20, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x72, + 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, 0x73, + 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x6c, 0x6f, + 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x65, 0x56, 0x65, 0x63, 0x33, 0x28, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, + 0x20, 0x70, 0x6f, 0x6f, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x71, 0x75, + 0x61, 0x74, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, + 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x51, 0x75, 0x61, 0x74, + 0x28, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, 0x20, 0x70, 0x6f, 0x6f, 0x6c, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6c, 0x6f, + 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x65, 0x4d, 0x61, 0x74, 0x34, 0x28, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, + 0x20, 0x70, 0x6f, 0x6f, 0x6c, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x50, + 0x6f, 0x6f, 0x6c, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x4d, 0x61, 0x74, + 0x68, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x3b, 0x0a, + 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x6c, + 0x69, 0x62, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x68, 0x0a, 0x20, 0x20, + 0x2f, 0x2f, 0x20, 0x43, 0x61, 0x72, 0x65, 0x66, 0x75, 0x6c, 0x2c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x73, 0x20, + 0x61, 0x62, 0x6f, 0x76, 0x65, 0x2c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x75, 0x73, 0x75, 0x61, 0x6c, 0x20, 0x43, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x0a, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x2a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x28, + 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x2a, 0x20, 0x75, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x73, 0x65, 0x74, 0x28, + 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, + 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x7a, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x5f, 0x61, 0x64, 0x64, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, + 0x76, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x75, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, + 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x76, 0x65, 0x63, 0x33, + 0x2a, 0x20, 0x76, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x64, 0x6f, 0x74, 0x28, 0x76, + 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x2a, 0x20, 0x75, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x2a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, + 0x28, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x2a, 0x20, 0x75, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x6c, 0x65, 0x72, + 0x70, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x2a, 0x20, 0x75, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x74, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x71, 0x75, 0x61, + 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, + 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x71, 0x75, + 0x61, 0x74, 0x2a, 0x20, 0x72, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x71, 0x75, + 0x61, 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x73, 0x65, 0x74, + 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x7a, 0x2c, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x77, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, + 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x41, 0x78, 0x69, + 0x73, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2c, 0x20, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x78, 0x2c, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x61, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x61, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x71, 0x75, 0x61, + 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, + 0x4d, 0x61, 0x74, 0x34, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, + 0x2c, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, + 0x5f, 0x6d, 0x75, 0x6c, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, + 0x2c, 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x72, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, + 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x71, + 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, + 0x75, 0x61, 0x74, 0x5f, 0x73, 0x6c, 0x65, 0x72, 0x70, 0x28, 0x71, 0x75, + 0x61, 0x74, 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, + 0x20, 0x72, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x71, 0x75, 0x61, + 0x74, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x71, 0x75, 0x61, + 0x74, 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, + 0x76, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x71, + 0x75, 0x61, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x67, 0x6c, 0x65, + 0x41, 0x78, 0x69, 0x73, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x78, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x79, 0x2c, 0x20, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x7a, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x75, 0x61, 0x74, 0x5f, + 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x28, 0x71, 0x75, 0x61, 0x74, + 0x2a, 0x20, 0x71, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x75, + 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x76, 0x29, 0x3b, 0x0a, + 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, + 0x34, 0x5f, 0x73, 0x65, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, + 0x6d, 0x2c, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6e, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, + 0x34, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x6d, + 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, + 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x69, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, + 0x61, 0x74, 0x34, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, + 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, + 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, 0x28, 0x6d, 0x61, + 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, + 0x20, 0x6e, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, + 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, + 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, + 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x7a, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, + 0x61, 0x74, 0x34, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, + 0x61, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, + 0x71, 0x75, 0x61, 0x74, 0x2a, 0x20, 0x71, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, + 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x73, + 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2a, 0x20, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2a, 0x20, 0x7a, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, + 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2a, 0x20, 0x61, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, + 0x20, 0x61, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, + 0x61, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, + 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x67, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, + 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x78, 0x2c, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x79, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x7a, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2a, 0x20, 0x73, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x2a, 0x20, 0x73, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2a, 0x20, 0x73, 0x7a, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, + 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x2a, 0x20, 0x61, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2a, 0x20, 0x61, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, + 0x20, 0x61, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x34, + 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x73, 0x65, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x6d, 0x61, 0x74, 0x34, + 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x79, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x7a, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x73, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, + 0x73, 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, 0x7a, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x67, 0x6c, + 0x65, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x78, 0x2c, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x79, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x6f, + 0x72, 0x74, 0x68, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x28, + 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6f, 0x70, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6e, 0x65, 0x61, 0x72, 0x2c, 0x20, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x66, 0x61, 0x72, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, + 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x28, + 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x6e, 0x65, 0x61, 0x72, 0x2c, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x20, 0x66, 0x61, 0x72, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x20, 0x66, 0x6f, 0x76, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x20, 0x61, 0x73, 0x70, 0x65, 0x63, 0x74, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x6c, + 0x6f, 0x6f, 0x6b, 0x41, 0x74, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2a, 0x20, + 0x6d, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x74, 0x6f, 0x2c, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x2a, 0x20, 0x75, 0x70, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x5f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x6d, 0x61, + 0x74, 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2a, 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, + 0x79, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x7a, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x74, + 0x34, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x61, 0x74, + 0x34, 0x2a, 0x20, 0x6d, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, + 0x20, 0x78, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x79, + 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x7a, 0x29, 0x3b, + 0x0a, 0x5d, 0x5d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x50, 0x6f, 0x6f, 0x6c, 0x3a, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2e, 0x2e, 0x2e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x43, 0x2e, 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x63, 0x33, 0x28, 0x63, + 0x61, 0x73, 0x74, 0x28, 0x27, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, 0x2a, 0x27, + 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x5b, 0x30, 0x5d, 0x29, 0x3a, + 0x73, 0x65, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x6f, + 0x6f, 0x6c, 0x3a, 0x71, 0x75, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, 0x2e, 0x6c, 0x6f, + 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x65, 0x51, 0x75, 0x61, 0x74, 0x28, 0x63, 0x61, 0x73, 0x74, 0x28, + 0x27, 0x50, 0x6f, 0x6f, 0x6c, 0x2a, 0x2a, 0x27, 0x2c, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x29, 0x5b, 0x30, 0x5d, 0x29, 0x3a, 0x73, 0x65, 0x74, 0x28, + 0x2e, 0x2e, 0x2e, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x6f, 0x6f, 0x6c, 0x3a, 0x6d, + 0x61, 0x74, 0x34, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x43, 0x2e, 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, + 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x4d, 0x61, + 0x74, 0x34, 0x28, 0x63, 0x61, 0x73, 0x74, 0x28, 0x27, 0x50, 0x6f, 0x6f, + 0x6c, 0x2a, 0x2a, 0x27, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x5b, + 0x30, 0x5d, 0x29, 0x3a, 0x73, 0x65, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x3d, 0x20, 0x43, 0x2e, 0x6c, 0x6f, 0x76, + 0x72, 0x4d, 0x61, 0x74, 0x68, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6f, 0x6c, + 0x28, 0x29, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2e, 0x2e, + 0x2e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, 0x2e, + 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x56, 0x65, 0x63, 0x33, 0x28, 0x70, 0x6f, 0x6f, + 0x6c, 0x29, 0x3a, 0x73, 0x65, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x28, 0x2e, + 0x2e, 0x2e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, + 0x2e, 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x65, 0x51, 0x75, 0x61, 0x74, 0x28, 0x70, 0x6f, + 0x6f, 0x6c, 0x29, 0x3a, 0x73, 0x65, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x28, + 0x2e, 0x2e, 0x2e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x43, 0x2e, 0x6c, 0x6f, 0x76, 0x72, 0x50, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x34, 0x28, 0x70, + 0x6f, 0x6f, 0x6c, 0x29, 0x3a, 0x73, 0x65, 0x74, 0x28, 0x2e, 0x2e, 0x2e, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x3d, 0x20, 0x66, 0x66, 0x69, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x76, 0x65, 0x63, 0x33, + 0x27, 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x71, 0x75, 0x61, + 0x74, 0x20, 0x3d, 0x20, 0x66, 0x66, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x6f, 0x66, 0x28, 0x27, 0x71, 0x75, 0x61, 0x74, 0x27, 0x29, 0x0a, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x3d, 0x20, + 0x66, 0x66, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x28, 0x27, + 0x6d, 0x61, 0x74, 0x34, 0x27, 0x29, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2c, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x78, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x78, 0x70, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x78, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6e, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x2c, + 0x20, 0x65, 0x78, 0x70, 0x20, 0x3d, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x2e, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x66, 0x6f, 0x28, 0x32, 0x2c, 0x20, + 0x27, 0x6e, 0x27, 0x29, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x69, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x27, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x23, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x69, 0x29, + 0x20, 0x6f, 0x72, 0x20, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x2c, 0x20, + 0x65, 0x78, 0x70, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x27, 0x42, 0x61, 0x64, 0x20, 0x25, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x25, 0x73, 0x20, 0x28, 0x25, 0x73, 0x20, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x67, 0x6f, 0x74, 0x20, 0x25, 0x73, + 0x29, 0x27, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x66, 0x6e, 0x2c, + 0x20, 0x65, 0x78, 0x70, 0x2c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x78, + 0x29, 0x29, 0x2c, 0x20, 0x33, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x76, 0x65, 0x63, 0x33, 0x20, 0x3d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2c, 0x20, + 0x27, 0x76, 0x65, 0x63, 0x33, 0x27, 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x20, + 0x3d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x71, 0x75, 0x61, 0x74, 0x2c, 0x20, 0x27, 0x71, 0x75, 0x61, 0x74, 0x27, + 0x29, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x3d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2c, 0x20, + 0x27, 0x6d, 0x61, 0x74, 0x34, 0x27, 0x29, 0x0a, 0x0a, 0x66, 0x66, 0x69, + 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x65, + 0x63, 0x33, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x43, 0x2e, 0x4d, 0x41, + 0x54, 0x48, 0x5f, 0x56, 0x45, 0x43, 0x33, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, + 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x2e, 0x78, 0x2c, 0x20, + 0x76, 0x2e, 0x79, 0x2c, 0x20, 0x76, 0x2e, 0x7a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x65, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x76, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x7a, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x78, + 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x73, 0x65, + 0x74, 0x28, 0x76, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x7a, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x78, 0x2c, 0x20, 0x31, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x76, + 0x65, 0x63, 0x33, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x76, 0x2c, 0x20, + 0x78, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x2c, + 0x20, 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2c, 0x20, 0x75, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x3a, 0x73, 0x65, + 0x74, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, + 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x61, 0x76, 0x65, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x76, 0x3a, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, + 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x76, 0x65, 0x63, + 0x33, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, + 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, + 0x2c, 0x20, 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2d, 0x2d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x43, 0x2e, + 0x76, 0x65, 0x63, 0x33, 0x5f, 0x64, 0x6f, 0x74, 0x28, 0x76, 0x2c, 0x20, + 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x75, 0x2e, + 0x78, 0x20, 0x2b, 0x20, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x75, 0x2e, + 0x79, 0x20, 0x2b, 0x20, 0x76, 0x2e, 0x7a, 0x20, 0x2a, 0x20, 0x75, 0x2e, + 0x7a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x2c, 0x20, + 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, + 0x33, 0x28, 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x2e, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, + 0x76, 0x2c, 0x20, 0x75, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x72, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x76, 0x2c, 0x20, 0x75, 0x2c, 0x20, 0x74, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x75, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x76, 0x65, + 0x63, 0x33, 0x5f, 0x6c, 0x65, 0x72, 0x70, 0x28, 0x76, 0x2c, 0x20, 0x75, + 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x5f, 0x5f, 0x61, 0x64, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x2c, 0x20, 0x75, 0x29, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x76, 0x2e, 0x78, 0x20, 0x2b, 0x20, 0x75, 0x2e, + 0x78, 0x2c, 0x20, 0x76, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x75, 0x2e, 0x79, + 0x2c, 0x20, 0x76, 0x2e, 0x7a, 0x20, 0x2b, 0x20, 0x75, 0x2e, 0x7a, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x73, 0x75, + 0x62, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x76, 0x2c, 0x20, 0x75, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x76, 0x2e, 0x78, 0x20, 0x2d, 0x20, 0x75, 0x2e, 0x78, 0x2c, 0x20, 0x76, + 0x2e, 0x79, 0x20, 0x2d, 0x20, 0x75, 0x2e, 0x79, 0x2c, 0x20, 0x76, 0x2e, + 0x7a, 0x20, 0x2d, 0x20, 0x75, 0x2e, 0x7a, 0x29, 0x20, 0x65, 0x6e, 0x64, + 0x2c, 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x6d, 0x75, 0x6c, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x2c, 0x20, + 0x75, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x76, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x75, 0x2e, 0x78, 0x2c, 0x20, 0x76, 0x2e, 0x79, 0x20, 0x2a, + 0x20, 0x75, 0x2e, 0x79, 0x2c, 0x20, 0x76, 0x2e, 0x7a, 0x20, 0x2a, 0x20, + 0x75, 0x2e, 0x7a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, + 0x5f, 0x5f, 0x64, 0x69, 0x76, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, 0x2c, 0x20, 0x75, 0x29, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x76, 0x2e, 0x78, 0x20, 0x2f, 0x20, 0x75, 0x2e, + 0x78, 0x2c, 0x20, 0x76, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x75, 0x2e, 0x79, + 0x2c, 0x20, 0x76, 0x2e, 0x7a, 0x20, 0x2f, 0x20, 0x75, 0x2e, 0x7a, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x75, 0x6e, + 0x6d, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x76, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, + 0x61, 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x76, 0x2e, + 0x78, 0x2c, 0x20, 0x2d, 0x76, 0x2e, 0x79, 0x2c, 0x20, 0x2d, 0x76, 0x2e, + 0x7a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x5f, 0x5f, + 0x6c, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x76, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x43, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x5f, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x20, + 0x20, 0x5f, 0x5f, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x76, + 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, + 0x28, 0x25, 0x66, 0x2c, 0x20, 0x25, 0x66, 0x2c, 0x20, 0x25, 0x66, 0x29, + 0x27, 0x2c, 0x20, 0x76, 0x2e, 0x78, 0x2c, 0x20, 0x76, 0x2e, 0x79, 0x2c, + 0x20, 0x76, 0x2e, 0x7a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x29, + 0x0a, 0x0a, 0x66, 0x66, 0x69, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2c, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, + 0x2c, 0x20, 0x72, 0x61, 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x72, + 0x61, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x71, + 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x2e, 0x79, 0x2c, 0x20, 0x71, 0x2e, 0x7a, + 0x2c, 0x20, 0x71, 0x2e, 0x77, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x6e, + 0x65, 0x77, 0x28, 0x27, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5b, 0x34, 0x5d, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x67, + 0x6c, 0x65, 0x41, 0x78, 0x69, 0x73, 0x28, 0x71, 0x2c, 0x20, 0x66, 0x20, + 0x2b, 0x20, 0x30, 0x2c, 0x20, 0x66, 0x20, 0x2b, 0x20, 0x31, 0x2c, 0x20, + 0x66, 0x20, 0x2b, 0x20, 0x32, 0x2c, 0x20, 0x66, 0x20, 0x2b, 0x20, 0x33, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x66, + 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x66, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x66, + 0x5b, 0x33, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, 0x2c, 0x20, 0x78, 0x2c, + 0x20, 0x79, 0x2c, 0x20, 0x7a, 0x2c, 0x20, 0x77, 0x2c, 0x20, 0x72, 0x61, + 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x78, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x79, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x72, 0x61, 0x77, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, + 0x5f, 0x73, 0x65, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, + 0x2c, 0x20, 0x7a, 0x2c, 0x20, 0x77, 0x29, 0x0a, 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, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3d, 0x20, + 0x6e, 0x65, 0x77, 0x28, 0x27, 0x76, 0x65, 0x63, 0x33, 0x5b, 0x31, 0x5d, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x5b, 0x30, 0x5d, 0x20, 0x3d, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x79, 0x2c, 0x20, 0x7a, 0x2c, 0x20, + 0x77, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x66, 0x72, + 0x6f, 0x6d, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x41, 0x78, 0x69, 0x73, 0x28, + 0x71, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x69, 0x73, 0x20, + 0x3d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x76, 0x65, 0x63, 0x33, 0x2c, 0x20, 0x78, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, + 0x2c, 0x20, 0x79, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, + 0x66, 0x20, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, 0x71, 0x75, 0x61, + 0x74, 0x2c, 0x20, 0x78, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, + 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x78, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, + 0x66, 0x20, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, 0x6d, 0x61, 0x74, + 0x34, 0x2c, 0x20, 0x78, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, + 0x74, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x4d, 0x61, 0x74, 0x34, 0x28, 0x71, + 0x2c, 0x20, 0x78, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x27, 0x45, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x20, 0x61, 0x20, 0x76, 0x65, 0x63, 0x33, 0x2c, 0x20, + 0x71, 0x75, 0x61, 0x74, 0x2c, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x2c, 0x20, + 0x6f, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x71, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, 0x2c, 0x20, 0x72, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2c, 0x20, 0x72, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3a, + 0x73, 0x65, 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x74, + 0x68, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x61, + 0x76, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x75, 0x61, 0x74, 0x2c, 0x20, + 0x71, 0x3a, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x71, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x6c, 0x65, 0x72, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, 0x2c, 0x20, 0x72, 0x2c, 0x20, + 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, + 0x74, 0x28, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x73, 0x6c, 0x65, 0x72, 0x70, 0x28, + 0x71, 0x2c, 0x20, 0x72, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x0a, 0x20, + 0x20, 0x5f, 0x5f, 0x6d, 0x75, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, 0x2c, 0x20, 0x72, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, + 0x74, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x2c, + 0x20, 0x72, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x20, 0x3d, + 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x72, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, + 0x61, 0x74, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x71, 0x2c, + 0x20, 0x76, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x72, 0x2c, 0x20, 0x27, + 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x61, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x20, 0x6f, 0x72, 0x20, 0x71, 0x75, 0x61, 0x74, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, + 0x2e, 0x71, 0x75, 0x61, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x6d, 0x75, 0x6c, + 0x28, 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x69, 0x6e, 0x69, 0x74, + 0x28, 0x6f, 0x75, 0x74, 0x2c, 0x20, 0x71, 0x29, 0x2c, 0x20, 0x72, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x71, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x43, 0x2e, 0x71, 0x75, 0x61, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x28, 0x71, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x0a, 0x20, 0x20, 0x5f, 0x5f, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x71, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x27, 0x28, 0x25, 0x66, 0x2c, 0x20, 0x25, 0x66, 0x2c, 0x20, 0x25, + 0x66, 0x2c, 0x20, 0x25, 0x66, 0x29, 0x27, 0x2c, 0x20, 0x71, 0x2e, 0x78, + 0x2c, 0x20, 0x71, 0x2e, 0x79, 0x2c, 0x20, 0x71, 0x2e, 0x7a, 0x2c, 0x20, + 0x71, 0x2e, 0x77, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x29, 0x0a, + 0x0a, 0x66, 0x66, 0x69, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x79, 0x70, + 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x2d, 0x2d, 0x20, + 0x79, 0x75, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x2e, 0x6d, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, + 0x31, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x32, 0x5d, 0x2c, 0x20, + 0x6d, 0x2e, 0x6d, 0x5b, 0x33, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x34, 0x5d, 0x2c, 0x20, + 0x6d, 0x2e, 0x6d, 0x5b, 0x35, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, + 0x36, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x37, 0x5d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, + 0x38, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x39, 0x5d, 0x2c, 0x20, + 0x6d, 0x2e, 0x6d, 0x5b, 0x31, 0x30, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, + 0x5b, 0x31, 0x31, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, 0x32, 0x5d, 0x2c, 0x20, 0x6d, + 0x2e, 0x6d, 0x5b, 0x31, 0x33, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, + 0x31, 0x34, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, 0x35, 0x5d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x2e, 0x6d, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, + 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x6d, + 0x2e, 0x6d, 0x5b, 0x33, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x34, 0x5d, 0x2c, 0x20, 0x6d, + 0x2e, 0x6d, 0x5b, 0x35, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x36, + 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x37, 0x5d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x38, + 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x39, 0x5d, 0x2c, 0x20, 0x6d, + 0x2e, 0x6d, 0x5b, 0x31, 0x30, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, + 0x31, 0x31, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, 0x32, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, + 0x6d, 0x5b, 0x31, 0x33, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, + 0x34, 0x5d, 0x2c, 0x20, 0x6d, 0x2e, 0x6d, 0x5b, 0x31, 0x35, 0x5d, 0x20, + 0x3d, 0x20, 0x2e, 0x2e, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x3a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, + 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x3a, 0x75, 0x6e, 0x70, 0x61, + 0x63, 0x6b, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x61, 0x76, 0x65, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, + 0x61, 0x74, 0x34, 0x28, 0x6d, 0x3a, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, + 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x6d, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x28, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, + 0x74, 0x34, 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x43, 0x2e, + 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x73, 0x65, 0x74, 0x28, 0x6f, 0x75, 0x74, + 0x2c, 0x20, 0x6d, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x28, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, + 0x74, 0x34, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, + 0x28, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x73, 0x65, 0x74, 0x28, + 0x6f, 0x75, 0x74, 0x2c, 0x20, 0x6d, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6d, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x7a, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x78, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x2c, 0x20, 0x78, 0x2c, + 0x20, 0x79, 0x2c, 0x20, 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x78, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x27, 0x76, 0x65, 0x63, 0x33, 0x20, + 0x6f, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, + 0x74, 0x34, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x6d, 0x2c, 0x20, 0x78, 0x2e, 0x78, 0x2c, 0x20, 0x78, 0x2e, 0x79, + 0x2c, 0x20, 0x78, 0x2e, 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x6f, 0x74, 0x61, 0x74, + 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6d, 0x2c, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x61, + 0x78, 0x2c, 0x20, 0x61, 0x79, 0x2c, 0x20, 0x61, 0x7a, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, + 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x61, 0x6e, 0x67, 0x6c, + 0x65, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x2c, 0x20, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x2c, 0x20, 0x61, 0x78, 0x2c, 0x20, 0x61, 0x79, 0x2c, 0x20, + 0x61, 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x71, 0x75, 0x61, 0x74, 0x28, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x27, 0x71, 0x75, 0x61, 0x74, + 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, + 0x61, 0x74, 0x34, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, + 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x20, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x2c, 0x20, 0x73, 0x78, 0x2c, + 0x20, 0x73, 0x79, 0x2c, 0x20, 0x73, 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, + 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x78, 0x29, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, + 0x6d, 0x2c, 0x20, 0x73, 0x78, 0x2c, 0x20, 0x73, 0x79, 0x2c, 0x20, 0x73, + 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x76, 0x65, 0x63, 0x33, 0x28, 0x73, 0x78, 0x2c, 0x20, + 0x31, 0x2c, 0x20, 0x27, 0x76, 0x65, 0x63, 0x33, 0x20, 0x6f, 0x72, 0x20, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x5f, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x6d, 0x2c, 0x20, 0x73, 0x78, 0x2e, + 0x78, 0x2c, 0x20, 0x73, 0x78, 0x2e, 0x79, 0x2c, 0x20, 0x73, 0x78, 0x2e, + 0x7a, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x67, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, + 0x74, 0x34, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x72, 0x74, 0x68, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, 0x28, + 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x41, 0x74, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x0a, 0x20, 0x20, + 0x5f, 0x5f, 0x6d, 0x75, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x2c, 0x20, 0x6e, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6d, 0x61, 0x74, 0x34, + 0x28, 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, + 0x73, 0x74, 0x79, 0x70, 0x65, 0x28, 0x6d, 0x61, 0x74, 0x34, 0x2c, 0x20, + 0x6e, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x74, 0x34, 0x28, + 0x6d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, + 0x61, 0x74, 0x34, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x79, + 0x28, 0x6f, 0x75, 0x74, 0x2c, 0x20, 0x6e, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x65, + 0x63, 0x33, 0x28, 0x6e, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x27, 0x6d, 0x61, + 0x74, 0x34, 0x20, 0x6f, 0x72, 0x20, 0x76, 0x65, 0x63, 0x33, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x66, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x28, 0x27, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x5b, 0x33, 0x5d, 0x27, 0x2c, 0x20, 0x6e, 0x2e, 0x78, + 0x2c, 0x20, 0x6e, 0x2e, 0x79, 0x2c, 0x20, 0x6e, 0x2e, 0x7a, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x2e, 0x6d, 0x61, 0x74, 0x34, + 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x6d, + 0x2c, 0x20, 0x66, 0x20, 0x2b, 0x20, 0x30, 0x2c, 0x20, 0x66, 0x20, 0x2b, + 0x20, 0x31, 0x2c, 0x20, 0x66, 0x20, 0x2b, 0x20, 0x32, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x76, 0x65, 0x63, 0x33, 0x28, 0x66, 0x5b, + 0x30, 0x5d, 0x2c, 0x20, 0x66, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x66, 0x5b, + 0x32, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x7d, 0x29, 0x0a +}; +unsigned int math_lua_len = 10065; diff --git a/src/api/types/mat4.c b/src/api/types/mat4.c new file mode 100644 index 00000000..c2ed2871 --- /dev/null +++ b/src/api/types/mat4.c @@ -0,0 +1,195 @@ +#include "api.h" +#include "api/math.h" +#include "math/math.h" +#include "lib/math.h" + +static int l_lovrMat4Unpack(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + for (int i = 0; i < 16; i++) { + lua_pushnumber(L, m[i]); + } + return 16; +} + +int l_lovrMat4Set(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + for (int i = 0; i < 16; i++) { + m[i] = luaL_checknumber(L, i); + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Copy(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4 n = lovrPoolAllocate(lovrMathGetPool(), MATH_MAT4); + mat4_init(n, m); + luax_pushlightmathtype(L, n, MATH_MAT4); + return 1; +} + +static int l_lovrMat4Save(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4 copy = lua_newuserdata(L, 16 * sizeof(float)); + mat4_init(copy, m); + luaL_getmetatable(L, "mat4"); + lua_setmetatable(L, -2); + return 1; +} + +static int l_lovrMat4Identity(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4_identity(m); + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Inverse(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4 n = lovrPoolAllocate(lovrMathGetPool(), MATH_MAT4); + mat4_invert(mat4_init(n, m)); + luax_pushlightmathtype(L, n, MATH_MAT4); + return 1; +} + +static int l_lovrMat4Transpose(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4 n = lovrPoolAllocate(lovrMathGetPool(), MATH_MAT4); + mat4_transpose(mat4_init(n, m)); + luax_pushlightmathtype(L, n, MATH_MAT4); + return 1; +} + +static int l_lovrMat4Translate(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + if (lua_type(L, 2) == LUA_TNUMBER) { + mat4_translate(m, luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4)); + } else { + float* v = luax_checkmathtype(L, 2, MATH_VEC3, "vec3 or number"); + mat4_translate(m, v[0], v[1], v[2]); + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Rotate(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + if (lua_type(L, 2) == LUA_TNUMBER) { + mat4_rotate(m, luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4), luaL_checknumber(L, 5)); + } else { + float* q = luax_checkmathtype(L, 2, MATH_QUAT, "quat or number"); + mat4_rotateQuat(m, q); + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Scale(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + if (lua_type(L, 2) == LUA_TNUMBER) { + float x = luaL_checknumber(L, 2); + mat4_scale(m, x, luaL_optnumber(L, 3, x), luaL_optnumber(L, 4, x)); + } else { + float* s = luax_checkmathtype(L, 2, MATH_VEC3, "vec3 or number"); + mat4_scale(m, s[0], s[1], s[2]); + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4GetTransform(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + float x, y, z, sx, sy, sz, angle, ax, ay, az; + mat4_getTransform(m, &x, &y, &z, &sx, &sy, &sz, &angle, &ax, &ay, &az); + lua_pushnumber(L, x); + lua_pushnumber(L, y); + lua_pushnumber(L, z); + lua_pushnumber(L, sx); + lua_pushnumber(L, sy); + lua_pushnumber(L, sz); + lua_pushnumber(L, angle); + lua_pushnumber(L, ax); + lua_pushnumber(L, ay); + lua_pushnumber(L, az); + return 10; +} + +static int l_lovrMat4SetTransform(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + float x = luaL_optnumber(L, 2, 0.); + float y = luaL_optnumber(L, 3, 0.); + float z = luaL_optnumber(L, 4, 0.); + float sx = luaL_optnumber(L, 5, 1.); + float sy = luaL_optnumber(L, 6, sx); + float sz = luaL_optnumber(L, 7, sx); + float angle = luaL_optnumber(L, 8, 0.); + float ax = luaL_optnumber(L, 9, 0.); + float ay = luaL_optnumber(L, 10, 1.); + float az = luaL_optnumber(L, 11, 0.); + mat4_setTransform(m, x, y, z, sx, sy, sz, angle, ax, ay, az); + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Perspective(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + float clipNear = luaL_checknumber(L, 2); + float clipFar = luaL_checknumber(L, 3); + float fov = luaL_checknumber(L, 4); + float aspect = luaL_checknumber(L, 5); + mat4_perspective(m, clipNear, clipFar, fov, aspect); + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4Orthographic(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + float left = luaL_checknumber(L, 2); + float right = luaL_checknumber(L, 3); + float top = luaL_checknumber(L, 4); + float bottom = luaL_checknumber(L, 5); + float clipNear = luaL_checknumber(L, 6); + float clipFar = luaL_checknumber(L, 7); + mat4_orthographic(m, left, right, top, bottom, clipNear, clipFar); + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4LookAt(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + float from[3] = { luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4) }; + float to[3] = { luaL_checknumber(L, 5), luaL_checknumber(L, 6), luaL_checknumber(L, 7) }; + float up[3] = { luaL_optnumber(L, 8, 0), luaL_optnumber(L, 9, 1), luaL_optnumber(L, 10, 0) }; + mat4_lookAt(m, from, to, up); + lua_settop(L, 1); + return 1; +} + +static int l_lovrMat4__mul(lua_State* L) { + mat4 m = luax_checkmathtype(L, 1, MATH_MAT4, NULL); + mat4 n = luax_checkmathtype(L, 2, MATH_MAT4, NULL); + mat4 out = lovrPoolAllocate(lovrMathGetPool(), MATH_MAT4); + mat4_multiply(mat4_init(out, m), n); + luax_pushlightmathtype(L, out, MATH_MAT4); + return 1; +} + +const luaL_Reg lovrMat4[] = { + { "unpack", l_lovrMat4Unpack }, + { "set", l_lovrMat4Set }, + { "copy", l_lovrMat4Copy }, + { "save", l_lovrMat4Save }, + { "identity", l_lovrMat4Identity }, + { "inverse", l_lovrMat4Inverse }, + { "transpose", l_lovrMat4Transpose }, + { "translate", l_lovrMat4Translate }, + { "rotate", l_lovrMat4Rotate }, + { "scale", l_lovrMat4Scale }, + { "getTransform", l_lovrMat4GetTransform }, + { "setTransform", l_lovrMat4SetTransform }, + { "perspective", l_lovrMat4Perspective }, + { "orthographic", l_lovrMat4Orthographic }, + { "lookAt", l_lovrMat4LookAt }, + { "__mul", l_lovrMat4__mul }, + { NULL, NULL } +}; diff --git a/src/api/types/pool.c b/src/api/types/pool.c new file mode 100644 index 00000000..8e31c03e --- /dev/null +++ b/src/api/types/pool.c @@ -0,0 +1,71 @@ +#include "api.h" +#include "api/math.h" +#include "math/pool.h" +#include "lib/math.h" + +int l_lovrPoolVec3(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + vec3 v = lovrPoolAllocate(pool, MATH_VEC3); + if (v) { + luax_pushlightmathtype(L, v, MATH_VEC3); + lua_replace(L, 1); + return l_lovrVec3Set(L); + } else { + lua_pushnil(L); + } + return 1; +} + +int l_lovrPoolQuat(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + quat q = lovrPoolAllocate(pool, MATH_QUAT); + if (q) { + luax_pushlightmathtype(L, q, MATH_QUAT); + lua_replace(L, 1); + return l_lovrQuatSet(L); + } else { + lua_pushnil(L); + } + return 1; +} + +int l_lovrPoolMat4(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + mat4 m = lovrPoolAllocate(pool, MATH_MAT4); + if (m) { + luax_pushlightmathtype(L, m, MATH_MAT4); + lua_replace(L, 1); + return l_lovrMat4Set(L); + } else { + lua_pushnil(L); + } + return 1; +} + +int l_lovrPoolDrain(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + lovrPoolDrain(pool); + return 0; +} + +int l_lovrPoolGetSize(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + lua_pushinteger(L, lovrPoolGetSize(pool)); + return 1; +} + +int l_lovrPoolGetUsage(lua_State* L) { + Pool* pool = luax_checktype(L, 1, Pool); + lua_pushinteger(L, lovrPoolGetUsage(pool)); + return 1; +} + +const luaL_Reg lovrPool[] = { + { "vec3", l_lovrPoolVec3 }, + { "quat", l_lovrPoolQuat }, + { "mat4", l_lovrPoolMat4 }, + { "drain", l_lovrPoolDrain }, + { "getSize", l_lovrPoolGetSize }, + { "getUsage", l_lovrPoolGetUsage }, + { NULL, NULL } +}; diff --git a/src/api/types/quat.c b/src/api/types/quat.c new file mode 100644 index 00000000..dd18ed7d --- /dev/null +++ b/src/api/types/quat.c @@ -0,0 +1,142 @@ +#include "api.h" +#include "api/math.h" +#include "math/math.h" + +static int l_lovrQuatUnpack(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + bool raw = lua_toboolean(L, 2); + if (raw) { + lua_pushnumber(L, q[0]); + lua_pushnumber(L, q[1]); + lua_pushnumber(L, q[2]); + lua_pushnumber(L, q[3]); + } else { + float angle, ax, ay, az; + quat_getAngleAxis(q, &angle, &ax, &ay, &az); + lua_pushnumber(L, angle); + lua_pushnumber(L, ax); + lua_pushnumber(L, ay); + lua_pushnumber(L, az); + } + return 4; +} + +int l_lovrQuatSet(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + if (lua_type(L, 2) == LUA_TNUMBER) { + float x = lua_tonumber(L, 2); + if (lua_type(L, 3) == LUA_TNUMBER) { + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + float w = luaL_checknumber(L, 5); + bool raw = lua_toboolean(L, 6); + if (raw) { + quat_set(q, x, y, z, w); + } else { + quat_fromAngleAxis(q, x, y, z, w); + } + } else { + vec3 axis = luax_checkmathtype(L, 3, MATH_VEC3, "vec3 or number"); + quat_fromAngleAxis(q, x, axis[0], axis[1], axis[2]); + } + } else { + MathType type; + float* p = luax_tomathtype(L, 2, &type); + if (!p) return luaL_typerror(L, 2, "vec3, quat, or number"); + + if (type == MATH_VEC3) { + if (lua_gettop(L) > 2) { + vec3 u = luax_checkmathtype(L, 3, MATH_VEC3, "vec3"); + quat_between(q, p, u); + } else { + quat_between(q, (float[3]) { 0.f, 0.f, -1.f }, p); + } + } else if (type == MATH_QUAT) { + quat_init(q, p); + } else if (type == MATH_MAT4) { + quat_fromMat4(q, p); + } else { + return luaL_typerror(L, 2, "vec3, quat, mat4, or number"); + } + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrQuatCopy(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + quat r = lovrPoolAllocate(lovrMathGetPool(), MATH_QUAT); + if (r) { + quat_init(r, q); + luax_pushlightmathtype(L, r, MATH_QUAT); + } else { + lua_pushnil(L); + } + return 1; +} + +static int l_lovrQuatSave(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + quat copy = lua_newuserdata(L, 4 * sizeof(float)); + quat_init(copy, q); + luaL_getmetatable(L, "quat"); + lua_setmetatable(L, -2); + return 1; +} + +static int l_lovrQuatNormalize(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + quat_normalize(q); + lua_settop(L, 1); + return 1; +} + +static int l_lovrQuatSlerp(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + quat r = luax_checkmathtype(L, 2, MATH_QUAT, NULL); + float t = luaL_checknumber(L, 3); + quat_slerp(q, r, t); + lua_settop(L, 1); + return 1; +} + +static int l_lovrQuat__mul(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + MathType type; + float* r = luax_tomathtype(L, 2, &type); + if (type == MATH_VEC3) { + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + quat_rotate(q, vec3_init(out, r)); + luax_pushlightmathtype(L, out, MATH_VEC3); + } else { + quat out = lovrPoolAllocate(lovrMathGetPool(), MATH_QUAT); + quat_mul(quat_init(out, q), r); + luax_pushlightmathtype(L, out, MATH_QUAT); + } + return 1; +} + +static int l_lovrQuat__len(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + lua_pushnumber(L, quat_length(q)); + return 1; +} + +static int l_lovrQuat__tostring(lua_State* L) { + quat q = luax_checkmathtype(L, 1, MATH_QUAT, NULL); + lua_pushfstring(L, "(%f, %f, %f, %f)", q[0], q[1], q[2], q[3]); + return 1; +} + +const luaL_Reg lovrQuat[] = { + { "unpack", l_lovrQuatUnpack }, + { "set", l_lovrQuatSet }, + { "copy", l_lovrQuatCopy }, + { "save", l_lovrQuatSave }, + { "normalize", l_lovrQuatNormalize }, + { "slerp", l_lovrQuatSlerp }, + { "__mul", l_lovrQuat__mul }, + { "__len", l_lovrQuat__len }, + { "__tostring", l_lovrQuat__tostring }, + { NULL, NULL } +}; diff --git a/src/api/types/vec3.c b/src/api/types/vec3.c new file mode 100644 index 00000000..8d5342df --- /dev/null +++ b/src/api/types/vec3.c @@ -0,0 +1,159 @@ +#include "api.h" +#include "api/math.h" +#include "math/math.h" +#include "lib/math.h" + +static int l_lovrVec3Unpack(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + lua_pushnumber(L, v[0]); + lua_pushnumber(L, v[1]); + lua_pushnumber(L, v[2]); + return 3; +} + +int l_lovrVec3Set(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + if (lua_type(L, 2) == LUA_TNUMBER) { + vec3_set(v, luaL_checknumber(L, 2), luaL_checknumber(L, 3), luaL_checknumber(L, 4)); + } else { + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, "vec3 or number"); + vec3_init(v, u); + } + lua_settop(L, 1); + return 1; +} + +static int l_lovrVec3Copy(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + if (out) { + vec3_init(out, v); + luax_pushlightmathtype(L, out, MATH_VEC3); + } else { + lua_pushnil(L); + } + return 1; +} + +static int l_lovrVec3Save(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 copy = lua_newuserdata(L, 4 * sizeof(float)); + vec3_init(copy, v); + luaL_getmetatable(L, "vec3"); + lua_setmetatable(L, -2); + return 1; +} + +static int l_lovrVec3Normalize(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3_normalize(v); + lua_settop(L, 1); + return 1; +} + +static int l_lovrVec3Dot(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, NULL); + lua_pushnumber(L, vec3_dot(v, u)); + return 1; +} + +static int l_lovrVec3Cross(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, NULL); + vec3_cross(v, u); + lua_settop(L, 1); + return 1; +} + +static int l_lovrVec3Lerp(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, NULL); + float t = luaL_checknumber(L, 3); + vec3_lerp(v, u, t); + lua_settop(L, 1); + return 1; +} + +static int l_lovrVec3__add(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + out[0] = v[0] + u[0], out[1] = v[1] + u[1], out[2] = v[2] + u[2]; + luax_pushlightmathtype(L, out, MATH_VEC3); + return 1; +} + +static int l_lovrVec3__sub(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + out[0] = v[0] - u[0], out[1] = v[1] - u[1], out[2] = v[2] - u[2]; + luax_pushlightmathtype(L, out, MATH_VEC3); + return 1; +} + +static int l_lovrVec3__mul(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + if (lua_type(L, 2) == LUA_TNUMBER) { + vec3_scale(vec3_init(out, v), lua_tonumber(L, 2)); + } else { + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, "vec3 or number"); + out[0] = v[0] * u[0], out[1] = v[1] * u[1], out[2] = v[2] * u[2]; + } + luax_pushlightmathtype(L, out, MATH_VEC3); + return 1; +} + +static int l_lovrVec3__div(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + if (lua_type(L, 2) == LUA_TNUMBER) { + vec3_scale(vec3_init(out, v), 1 / lua_tonumber(L, 2)); + } else { + vec3 u = luax_checkmathtype(L, 2, MATH_VEC3, "vec3 or number"); + out[0] = v[0] / u[0], out[1] = v[1] / u[1], out[2] = v[2] / u[2]; + } + luax_pushlightmathtype(L, out, MATH_VEC3); + return 1; +} + +static int l_lovrVec3__unm(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + vec3 out = lovrPoolAllocate(lovrMathGetPool(), MATH_VEC3); + vec3_scale(vec3_init(out, v), -1.f); + luax_pushlightmathtype(L, out, MATH_VEC3); + return 1; +} + +static int l_lovrVec3__len(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + lua_pushnumber(L, vec3_length(v)); + return 1; +} + +static int l_lovrVec3__tostring(lua_State* L) { + vec3 v = luax_checkmathtype(L, 1, MATH_VEC3, NULL); + lua_pushfstring(L, "(%f, %f, %f)", v[0], v[1], v[2]); + return 1; +} + +const luaL_Reg lovrVec3[] = { + { "unpack", l_lovrVec3Unpack }, + { "set", l_lovrVec3Set }, + { "copy", l_lovrVec3Copy }, + { "save", l_lovrVec3Save }, + { "normalize", l_lovrVec3Normalize }, + { "dot", l_lovrVec3Dot }, + { "cross", l_lovrVec3Cross }, + { "lerp", l_lovrVec3Lerp }, + { "__add", l_lovrVec3__add }, + { "__sub", l_lovrVec3__sub }, + { "__mul", l_lovrVec3__mul }, + { "__div", l_lovrVec3__div }, + { "__unm", l_lovrVec3__unm }, + { "__len", l_lovrVec3__len }, + { "__tostring", l_lovrVec3__tostring }, + { NULL, NULL } +}; diff --git a/src/audio/audio.c b/src/audio/audio.c index 8f2120c0..f2c884bc 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -171,7 +171,7 @@ void lovrAudioSetOrientation(float angle, float ax, float ay, float az) { // Rotate the unit forward/up vectors by the quaternion derived from the specified angle/axis float f[3] = { 0, 0, -1 }; float u[3] = { 0, 1, 0 }; - quat_fromAngleAxis(state.orientation, angle, (float[3]) { ax, ay, az }); + quat_fromAngleAxis(state.orientation, angle, ax, ay, az); quat_rotate(state.orientation, f); quat_rotate(state.orientation, u); diff --git a/src/lib/math.c b/src/lib/math.c index fb57ab8b..0078a2e1 100644 --- a/src/lib/math.c +++ b/src/lib/math.c @@ -1,4 +1,5 @@ #include "math.h" +#define _USE_MATH_DEFINES #include #include #ifdef LOVR_USE_SSE @@ -74,13 +75,14 @@ quat quat_set(quat q, float x, float y, float z, float w) { return q; } -quat quat_fromAngleAxis(quat q, float angle, vec3 axis) { - vec3_normalize(axis); +quat quat_fromAngleAxis(quat q, float angle, float ax, float ay, float az) { + float length = sqrt(ax * ax + ay * ay + az * az); + length = length == 0. ? 1. : length; float s = sin(angle * .5f); float c = cos(angle * .5f); - q[0] = s * axis[0]; - q[1] = s * axis[1]; - q[2] = s * axis[2]; + q[0] = s * ax / length; + q[1] = s * ay / length; + q[2] = s * az / length; q[3] = c; return q; } @@ -103,6 +105,15 @@ quat quat_fromMat4(quat q, mat4 m) { return q; } +quat quat_mul(quat q, quat r) { + return quat_set(q, + q[0] * r[3] + q[3] * r[0] - q[1] * r[2] - q[2] * r[1], + q[1] * r[3] + q[3] * r[1] - q[2] * r[0] - q[0] * r[2], + q[2] * r[3] + q[3] * r[2] - q[0] * r[1] - q[1] * r[0], + q[3] * r[3] - q[0] * r[0] - q[1] * r[1] - q[2] * r[2] + ); +} + quat quat_normalize(quat q) { float len = quat_length(q); if (len == 0) { @@ -185,6 +196,27 @@ void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z) { *z = q[2] * s; } +quat quat_between(quat q, vec3 u, vec3 v) { + float dot = vec3_dot(u, v); + if (dot > .99999) { + q[0] = q[1] = q[2] = 0.f; + q[3] = 1.f; + return q; + } else if (dot < -.99999) { + float axis[3]; + vec3_cross(vec3_set(axis, 1, 0, 0), u); + if (vec3_length(axis) < .00001) { + vec3_cross(vec3_set(axis, 0, 1, 0), u); + } + vec3_normalize(axis); + quat_fromAngleAxis(q, M_PI, axis[0], axis[1], axis[2]); + return q; + } + vec3_cross(vec3_init(q, u), v); + q[3] = 1 + dot; + return quat_normalize(q); +} + // mat4 mat4 mat4_set(mat4 m, mat4 n) { @@ -406,8 +438,7 @@ mat4 mat4_translate(mat4 m, float x, float y, float z) { mat4 mat4_rotate(mat4 m, float angle, float x, float y, float z) { float q[4]; - float v[3]; - quat_fromAngleAxis(q, angle, vec3_set(v, x, y, z)); + quat_fromAngleAxis(q, angle, x, y, z); return mat4_rotateQuat(m, q); } diff --git a/src/lib/math.h b/src/lib/math.h index 4f347553..6e5c9387 100644 --- a/src/lib/math.h +++ b/src/lib/math.h @@ -18,13 +18,15 @@ vec3 vec3_lerp(vec3 v, vec3 u, float t); // quat quat quat_init(quat q, quat r); quat quat_set(quat q, float x, float y, float z, float w); -quat quat_fromAngleAxis(quat q, float angle, vec3 axis); +quat quat_fromAngleAxis(quat q, float angle, float ax, float ay, float az); quat quat_fromMat4(quat q, mat4 m); +quat quat_mul(quat q, quat r); quat quat_normalize(quat q); float quat_length(quat q); quat quat_slerp(quat q, quat r, float t); void quat_rotate(quat q, vec3 v); void quat_getAngleAxis(quat q, float* angle, float* x, float* y, float* z); +quat quat_between(quat q, vec3 u, vec3 v); // mat4 #define MAT4_IDENTITY { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 } diff --git a/src/math/math.c b/src/math/math.c index 2256ecce..02b75224 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -7,20 +7,26 @@ static MathState state; -bool lovrMathInit() { +bool lovrMathInit(size_t poolSize) { if (state.initialized) return false; + state.pool = lovrPoolCreate(poolSize); state.generator = lovrRandomGeneratorCreate(); Seed seed = { .b64 = (uint64_t) time(0) }; - lovrRandomGeneratorSetSeed(state.generator, seed); + lovrRandomGeneratorSetSeed(state.generator, seed); return state.initialized = true; } void lovrMathDestroy() { if (!state.initialized) return; + lovrRelease(state.pool); lovrRelease(state.generator); memset(&state, 0, sizeof(MathState)); } +Pool* lovrMathGetPool() { + return state.pool; +} + RandomGenerator* lovrMathGetRandomGenerator() { return state.generator; } diff --git a/src/math/math.h b/src/math/math.h index 0e51fc1f..54031bcc 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -1,3 +1,4 @@ +#include "math/pool.h" #include "math/randomGenerator.h" #include "lib/math.h" #include @@ -7,10 +8,12 @@ typedef struct { bool initialized; RandomGenerator* generator; + Pool* pool; } MathState; -bool lovrMathInit(); +bool lovrMathInit(size_t poolSize); void lovrMathDestroy(); +Pool* lovrMathGetPool(); RandomGenerator* lovrMathGetRandomGenerator(); void lovrMathOrientationToDirection(float angle, float ax, float ay, float az, vec3 v); float lovrMathGammaToLinear(float x); diff --git a/src/math/pool.c b/src/math/pool.c new file mode 100644 index 00000000..88cec3fb --- /dev/null +++ b/src/math/pool.c @@ -0,0 +1,51 @@ +#include "math/pool.h" +#include + +static const size_t sizeOfMathType[] = { + [MATH_VEC3] = 4 * sizeof(float), + [MATH_QUAT] = 4 * sizeof(float), + [MATH_MAT4] = 16 * sizeof(float) +}; + +Pool* lovrPoolCreate(size_t size) { + Pool* pool = lovrAlloc(Pool, lovrPoolDestroy); + if (!pool) return NULL; + + pool->size = size; + pool->data = calloc(1, size + POOL_ALIGN - 1); + pool->head = (uint8_t*) ALIGN((uint8_t*) pool->data + POOL_ALIGN - 1, POOL_ALIGN); + lovrAssert(pool->data, "Could not allocate Pool memory"); + pool->usage = 0; + + return pool; +} + +void lovrPoolDestroy(void* ref) { + Pool* pool = ref; + free(pool->data); + free(pool); +} + +float* lovrPoolAllocate(Pool* pool, MathType type) { + size_t size = sizeOfMathType[type]; + if (pool->usage + size > pool->size) return NULL; + float* p = (float*) (pool->head + pool->usage); + pool->usage += size; + return p; +} + +void lovrPoolDrain(Pool* pool) { + pool->usage = 0; +} + +size_t lovrPoolGetSize(Pool* pool) { + return pool->size; +} + +size_t lovrPoolGetUsage(Pool* pool) { + return pool->usage; +} + +float* lovrPoolAllocateVec3(Pool* pool) { return lovrPoolAllocate(pool, MATH_VEC3); } +float* lovrPoolAllocateQuat(Pool* pool) { return lovrPoolAllocate(pool, MATH_QUAT); } +float* lovrPoolAllocateMat4(Pool* pool) { return lovrPoolAllocate(pool, MATH_MAT4); } diff --git a/src/math/pool.h b/src/math/pool.h new file mode 100644 index 00000000..b9ec9596 --- /dev/null +++ b/src/math/pool.h @@ -0,0 +1,33 @@ +#include "util.h" + +#define POOL_ALIGN 16 +#define DEFAULT_POOL_SIZE (640 * 1024) + +#pragma once + +typedef enum { + MATH_VEC3, + MATH_QUAT, + MATH_MAT4, + MAX_MATH_TYPES +} MathType; + +typedef struct { + Ref ref; + float* data; + size_t size; + size_t usage; + uint8_t* head; +} Pool; + +Pool* lovrPoolCreate(size_t size); +void lovrPoolDestroy(void* ref); +float* lovrPoolAllocate(Pool* pool, MathType type); +void lovrPoolDrain(Pool* pool); +size_t lovrPoolGetSize(Pool* pool); +size_t lovrPoolGetUsage(Pool* pool); + +// For you, LuaJIT +float* lovrPoolNewVec3(Pool* pool); +float* lovrPoolNewQuat(Pool* pool); +float* lovrPoolNewMat4(Pool* pool); diff --git a/src/physics/physics.c b/src/physics/physics.c index 666ab2d2..6c6f0123 100644 --- a/src/physics/physics.c +++ b/src/physics/physics.c @@ -531,8 +531,7 @@ void lovrColliderGetOrientation(Collider* collider, float* angle, float* x, floa void lovrColliderSetOrientation(Collider* collider, float angle, float x, float y, float z) { float quaternion[4]; - float axis[3] = { x, y, z }; - quat_fromAngleAxis(quaternion, angle, axis); + quat_fromAngleAxis(quaternion, angle, x, y, z); float q[4] = { quaternion[3], quaternion[0], quaternion[1], quaternion[2] }; dBodySetQuaternion(collider->body, q); } @@ -730,8 +729,7 @@ void lovrShapeGetOrientation(Shape* shape, float* angle, float* x, float* y, flo void lovrShapeSetOrientation(Shape* shape, float angle, float x, float y, float z) { float quaternion[4]; - float axis[3] = { x, y, z }; - quat_fromAngleAxis(quaternion, angle, axis); + quat_fromAngleAxis(quaternion, angle, x, y, z); float q[4] = { quaternion[3], quaternion[0], quaternion[1], quaternion[2] }; dGeomSetOffsetQuaternion(shape->id, q); } diff --git a/src/resources/boot.lua b/src/resources/boot.lua index 034025d2..d77324d7 100644 --- a/src/resources/boot.lua +++ b/src/resources/boot.lua @@ -67,6 +67,9 @@ function lovr.boot() offset = 1.7, msaa = 4 }, + math = { + poolsize = 640 * 1024 + }, window = { width = 1080, height = 600, @@ -141,6 +144,7 @@ function lovr.run() end lovr.graphics.present() end + if lovr.math then lovr.math.drain() end end end diff --git a/src/resources/boot.lua.h b/src/resources/boot.lua.h index de65d099..b9bc2159 100644 --- a/src/resources/boot.lua.h +++ b/src/resources/boot.lua.h @@ -173,6 +173,10 @@ unsigned char boot_lua[] = { 0x20, 0x20, 0x20, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x37, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x34, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x74, 0x68, + 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, + 0x6f, 0x6f, 0x6c, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x36, 0x34, + 0x30, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x32, 0x34, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x38, @@ -350,275 +354,279 @@ unsigned char boot_lua[] = { 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, - 0x6b, 0x28, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x27, 0x5c, 0x6e, - 0x5b, 0x5e, 0x5c, 0x6e, 0x5d, 0x2b, 0x24, 0x27, 0x2c, 0x20, 0x27, 0x27, - 0x29, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x27, 0x5c, 0x74, 0x27, 0x2c, - 0x20, 0x27, 0x27, 0x29, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x27, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, - 0x63, 0x6b, 0x27, 0x2c, 0x20, 0x27, 0x5c, 0x6e, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x27, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, - 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, - 0x6b, 0x29, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, - 0x6b, 0x28, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, - 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x32, - 0x29, 0x29, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6d, 0x61, 0x74, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x6d, + 0x61, 0x74, 0x68, 0x2e, 0x64, 0x72, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x73, 0x29, + 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x3a, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x27, 0x5c, 0x6e, 0x5b, 0x5e, 0x5c, 0x6e, + 0x5d, 0x2b, 0x24, 0x27, 0x2c, 0x20, 0x27, 0x27, 0x29, 0x3a, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x27, 0x5c, 0x74, 0x27, 0x2c, 0x20, 0x27, 0x27, 0x29, + 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x27, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x27, 0x2c, + 0x20, 0x27, 0x5c, 0x6e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x27, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, + 0x6e, 0x64, 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x0a, 0x20, + 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, + 0x5c, 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x6f, 0x72, 0x20, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, + 0x63, 0x6b, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x32, 0x29, 0x29, 0x0a, 0x20, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, - 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x20, - 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, - 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x31, - 0x30, 0x35, 0x2c, 0x20, 0x2e, 0x30, 0x39, 0x38, 0x2c, 0x20, 0x2e, 0x31, - 0x33, 0x37, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, - 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x38, 0x36, 0x33, 0x2c, 0x20, 0x2e, - 0x38, 0x36, 0x33, 0x2c, 0x20, 0x2e, 0x38, 0x36, 0x33, 0x29, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, - 0x64, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, - 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x73, - 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x28, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, - 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, - 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x29, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, - 0x65, 0x6c, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, - 0x66, 0x6f, 0x6e, 0x74, 0x3a, 0x67, 0x65, 0x74, 0x50, 0x69, 0x78, 0x65, - 0x6c, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x28, 0x29, 0x0a, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, - 0x20, 0x3d, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x3a, 0x67, 0x65, 0x74, 0x57, - 0x69, 0x64, 0x74, 0x68, 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2c, 0x20, 0x2e, 0x35, 0x35, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, - 0x6c, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x29, 0x0a, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x2d, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x32, 0x2c, 0x20, 0x30, 0x2c, 0x20, - 0x2d, 0x32, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, - 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x2e, 0x35, 0x35, 0x20, - 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x44, 0x65, 0x6e, 0x73, 0x69, - 0x74, 0x79, 0x2c, 0x20, 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x63, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, - 0x20, 0x69, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x71, 0x75, 0x69, 0x74, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x20, 0x65, 0x6e, 0x64, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, - 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, - 0x6c, 0x65, 0x61, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, - 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, - 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, - 0x61, 0x64, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, - 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, - 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x6f, 0x28, 0x72, 0x65, 0x6e, - 0x64, 0x65, 0x72, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, + 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, + 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x2e, 0x31, 0x30, 0x35, 0x2c, 0x20, + 0x2e, 0x30, 0x39, 0x38, 0x2c, 0x20, 0x2e, 0x31, 0x33, 0x37, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, - 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, - 0x76, 0x72, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x28, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x2c, 0x20, 0x65, - 0x72, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, - 0x27, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x5c, 0x6e, 0x5c, 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x65, 0x72, - 0x72, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, - 0x73, 0x20, 0x75, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x6c, 0x75, 0x61, 0x78, 0x5f, 0x67, 0x65, 0x74, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x73, 0x6f, 0x20, 0x69, 0x74, 0x20, - 0x6c, 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, - 0x6d, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x2e, 0x20, - 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x73, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, - 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x6c, 0x69, - 0x6e, 0x65, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x27, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, - 0x63, 0x6b, 0x3a, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, - 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, - 0x74, 0x4f, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4c, 0x69, 0x6e, 0x65, - 0x28, 0x73, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x72, 0x65, - 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x3a, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x74, 0x3a, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, - 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x73, 0x6c, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x23, 0x73, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x23, 0x73, 0x20, - 0x2d, 0x20, 0x61, 0x74, 0x20, 0x2d, 0x20, 0x23, 0x74, 0x20, 0x2b, 0x20, - 0x32, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x73, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x31, 0x2c, 0x20, 0x61, - 0x74, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x73, 0x3a, 0x73, 0x75, 0x62, 0x28, - 0x61, 0x74, 0x2c, 0x73, 0x6c, 0x65, 0x6e, 0x29, 0x20, 0x2e, 0x2e, 0x20, - 0x27, 0x5c, 0x6e, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, - 0x2c, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x20, - 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, - 0x6e, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x63, 0x6f, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x0a, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, - 0x72, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6f, 0x6e, - 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, - 0x20, 0x6f, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, - 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x65, 0x2c, 0x20, 0x74, 0x62, - 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, - 0x20, 0x74, 0x6f, 0x20, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, - 0x74, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x63, 0x6c, - 0x65, 0x61, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, - 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, 0x68, - 0x61, 0x6e, 0x64, 0x28, 0x65, 0x2c, 0x20, 0x74, 0x62, 0x29, 0x20, 0x6f, - 0x72, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x63, 0x6c, 0x65, 0x61, 0x6e, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x64, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, - 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x28, 0x65, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, - 0x6b, 0x28, 0x74, 0x62, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, - 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, - 0x27, 0x27, 0x2c, 0x20, 0x32, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x62, + 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x28, 0x2e, 0x38, 0x36, 0x33, 0x2c, 0x20, 0x2e, 0x38, 0x36, 0x33, 0x2c, + 0x20, 0x2e, 0x38, 0x36, 0x33, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, + 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x69, + 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x28, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, + 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x44, 0x65, + 0x6e, 0x73, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x3a, 0x67, 0x65, 0x74, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x44, 0x65, 0x6e, + 0x73, 0x69, 0x74, 0x79, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, + 0x28, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x2e, 0x35, + 0x35, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x44, 0x65, 0x6e, + 0x73, 0x69, 0x74, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, + 0x73, 0x2e, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2c, 0x20, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, + 0x2f, 0x20, 0x32, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x2d, 0x32, 0x30, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x30, 0x2c, 0x20, 0x2e, 0x35, 0x35, 0x20, 0x2a, 0x20, 0x70, 0x69, + 0x78, 0x65, 0x6c, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x2c, 0x20, + 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x6e, 0x20, + 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, + 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x20, 0x69, 0x66, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x71, 0x75, 0x69, + 0x74, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, + 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x73, 0x65, 0x74, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x54, 0x6f, 0x28, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x29, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, + 0x76, 0x72, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x74, + 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, + 0x68, 0x72, 0x65, 0x61, 0x64, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x27, 0x54, 0x68, 0x72, + 0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5c, 0x6e, 0x5c, + 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x30, + 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x20, 0x75, 0x70, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x6c, 0x75, 0x61, 0x78, 0x5f, 0x67, 0x65, 0x74, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x20, 0x73, 0x6f, 0x20, 0x69, 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, + 0x73, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x20, 0x70, 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x0a, 0x2d, 0x2d, + 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, + 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x27, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x6e, 0x65, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x4f, 0x6e, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x4c, 0x69, 0x6e, 0x65, 0x28, 0x73, 0x2c, 0x20, + 0x74, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, + 0x74, 0x20, 0x3d, 0x20, 0x73, 0x3a, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x28, 0x29, 0x3a, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x3a, 0x72, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x6c, 0x65, + 0x6e, 0x20, 0x3d, 0x20, 0x23, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x74, 0x20, 0x3d, 0x20, 0x28, 0x23, 0x73, 0x20, 0x2d, 0x20, 0x61, 0x74, + 0x20, 0x2d, 0x20, 0x23, 0x74, 0x20, 0x2b, 0x20, 0x32, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x3a, + 0x73, 0x75, 0x62, 0x28, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x2d, 0x32, 0x29, + 0x2c, 0x20, 0x73, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x61, 0x74, 0x2c, 0x73, + 0x6c, 0x65, 0x6e, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, 0x27, + 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x2c, 0x20, 0x27, 0x27, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x72, 0x75, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x74, + 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x63, 0x6f, 0x72, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x65, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, + 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, + 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, + 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, + 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x63, + 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6e, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x28, 0x65, 0x2c, 0x20, 0x74, 0x62, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, + 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x20, 0x6f, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x28, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, + 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, + 0x65, 0x2c, 0x20, 0x74, 0x62, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x73, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x62, 0x6f, 0x6f, 0x74, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x72, 0x75, 0x6e, - 0x2e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, - 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x77, 0x61, 0x72, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x6c, 0x6c, - 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6c, - 0x6f, 0x76, 0x72, 0x2e, 0x72, 0x75, 0x6e, 0x27, 0x73, 0x20, 0x70, 0x65, - 0x72, 0x2d, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, - 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, - 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x78, 0x70, - 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x62, 0x6f, - 0x6f, 0x74, 0x2c, 0x20, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, - 0x0a, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, - 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x2d, 0x2d, 0x20, 0x4c, 0x75, 0x61, 0x4a, 0x49, 0x54, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x78, - 0x65, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x66, - 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, - 0x63, 0x75, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x78, - 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x20, - 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, - 0x20, 0x74, 0x6f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, - 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x2e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x6f, 0x6b, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x20, 0x3d, 0x20, 0x78, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x63, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, - 0x20, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, - 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x6b, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x62, - 0x79, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x72, 0x2e, 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x20, 0x69, 0x74, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x2e, 0x0a, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, - 0x20, 0x63, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2e, 0x79, - 0x69, 0x65, 0x6c, 0x64, 0x28, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x20, 0x74, 0x6f, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x2d, 0x2d, 0x20, 0x41, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, - 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x70, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x70, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x4f, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4c, 0x69, 0x6e, - 0x65, 0x28, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x2c, 0x20, 0x27, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x6e, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x70, 0x61, 0x72, - 0x74, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x61, 0x72, 0x74, - 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, - 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, - 0x68, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x20, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x6f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x6e, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, + 0x5c, 0x6e, 0x27, 0x20, 0x2e, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, + 0x65, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x74, 0x62, + 0x20, 0x6f, 0x72, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x27, 0x27, 0x2c, 0x20, + 0x32, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x63, + 0x6c, 0x65, 0x61, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x73, 0x20, 0x6c, 0x6f, + 0x76, 0x72, 0x2e, 0x62, 0x6f, 0x6f, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x72, 0x75, 0x6e, 0x2e, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x2c, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, + 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x72, 0x2e, + 0x72, 0x75, 0x6e, 0x27, 0x73, 0x20, 0x70, 0x65, 0x72, 0x2d, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x72, 0x72, 0x68, 0x61, + 0x6e, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x5f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x78, 0x70, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x62, 0x6f, 0x6f, 0x74, 0x2c, 0x20, + 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x0a, 0x0a, 0x20, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, + 0x4c, 0x75, 0x61, 0x4a, 0x49, 0x54, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6e, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x73, + 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x78, 0x70, 0x63, 0x61, 0x6c, + 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x27, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, + 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x61, 0x6e, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, + 0x6b, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, + 0x78, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6f, 0x6e, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6f, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x2d, 0x2d, + 0x20, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x69, 0x73, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x74, + 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x20, 0x69, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x2e, + 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x20, 0x69, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6e, 0x65, 0x77, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2e, 0x79, 0x69, 0x65, 0x6c, 0x64, + 0x28, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x74, 0x6f, 0x20, + 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x41, + 0x20, 0x6d, 0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, + 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x70, + 0x61, 0x72, 0x74, 0x2c, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x61, + 0x72, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x4f, 0x6e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x4c, 0x69, 0x6e, 0x65, 0x28, 0x65, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2c, 0x20, 0x27, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, + 0x61, 0x63, 0x6b, 0x3a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x70, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x70, 0x61, 0x72, 0x74, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x6c, 0x6f, 0x76, 0x72, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a }; -unsigned int boot_lua_len = 7451; +unsigned int boot_lua_len = 7543; diff --git a/src/util.h b/src/util.h index 9d7b896e..54276109 100644 --- a/src/util.h +++ b/src/util.h @@ -12,6 +12,8 @@ #define MIN(a, b) (a < b ? a : b) #define CLAMP(x, min, max) MAX(min, MIN(max, x)) +#define ALIGN(p, n) ((uintptr_t) p & -n) + typedef struct ref { int count; const char* type;