From 9d5243a410b09a513aff7175bca2e0f1519ac254 Mon Sep 17 00:00:00 2001 From: penguindark <57967770+penguindark@users.noreply.github.com> Date: Fri, 12 Feb 2021 00:42:10 +0100 Subject: [PATCH] examples: add an example of march tracing in glsl, first release (#8689) --- examples/sokol/rt_glsl/HandmadeMath.h | 3240 ++++++++++++++++++++++ examples/sokol/rt_glsl/default_include.h | 27 + examples/sokol/rt_glsl/rt_glsl.glsl | 695 +++++ examples/sokol/rt_glsl/rt_glsl.h | 2686 ++++++++++++++++++ examples/sokol/rt_glsl/rt_glsl.v | 422 +++ examples/sokol/rt_glsl/v.mod | 0 6 files changed, 7070 insertions(+) create mode 100644 examples/sokol/rt_glsl/HandmadeMath.h create mode 100644 examples/sokol/rt_glsl/default_include.h create mode 100644 examples/sokol/rt_glsl/rt_glsl.glsl create mode 100644 examples/sokol/rt_glsl/rt_glsl.h create mode 100644 examples/sokol/rt_glsl/rt_glsl.v create mode 100644 examples/sokol/rt_glsl/v.mod diff --git a/examples/sokol/rt_glsl/HandmadeMath.h b/examples/sokol/rt_glsl/HandmadeMath.h new file mode 100644 index 0000000000..a33e0ef715 --- /dev/null +++ b/examples/sokol/rt_glsl/HandmadeMath.h @@ -0,0 +1,3240 @@ +/* + HandmadeMath.h v1.11.0 + + This is a single header file with a bunch of useful functions for game and + graphics math operations. + + ============================================================================= + + You MUST + + #define HANDMADE_MATH_IMPLEMENTATION + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #include "HandmadeMath.h" + + All other files should just #include "HandmadeMath.h" without the #define. + + ============================================================================= + + To disable SSE intrinsics, you MUST + + #define HANDMADE_MATH_NO_SSE + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_NO_SSE + #include "HandmadeMath.h" + + ============================================================================= + + If you would prefer not to use the HMM_ prefix on function names, you can + + #define HMM_PREFIX + + To use a custom prefix instead, you can + + #define HMM_PREFIX(name) YOUR_PREFIX_##name + + ============================================================================= + + To use HandmadeMath without the CRT, you MUST + + #define HMM_SINF MySinF + #define HMM_COSF MyCosF + #define HMM_TANF MyTanF + #define HMM_SQRTF MySqrtF + #define HMM_EXPF MyExpF + #define HMM_LOGF MyLogF + #define HMM_ACOSF MyACosF + #define HMM_ATANF MyATanF + #define HMM_ATAN2F MYATan2F + + Provide your own implementations of SinF, CosF, TanF, ACosF, ATanF, ATan2F, + ExpF, and LogF in EXACTLY one C or C++ file that includes this header, + BEFORE the include, like this: + + #define HMM_SINF MySinF + #define HMM_COSF MyCosF + #define HMM_TANF MyTanF + #define HMM_SQRTF MySqrtF + #define HMM_EXPF MyExpF + #define HMM_LOGF MyLogF + #define HMM_ACOSF MyACosF + #define HMM_ATANF MyATanF + #define HMM_ATAN2F MyATan2F + #define HANDMADE_MATH_IMPLEMENTATION + #include "HandmadeMath.h" + + If you do not define all of these, HandmadeMath.h will use the + versions of these functions that are provided by the CRT. + + ============================================================================= + + LICENSE + + This software is in the public domain. Where that dedication is not + recognized, you are granted a perpetual, irrevocable license to copy, + distribute, and modify this file as you see fit. + + CREDITS + + Written by Zakary Strange (strangezak@gmail.com && @strangezak) + + Functionality: + Matt Mascarenhas (@miblo_) + Aleph + FieryDrake (@fierydrake) + Gingerbill (@TheGingerBill) + Ben Visness (@bvisness) + Trinton Bullard (@Peliex_Dev) + @AntonDan + + Fixes: + Jeroen van Rijn (@J_vanRijn) + Kiljacken (@Kiljacken) + Insofaras (@insofaras) + Daniel Gibson (@DanielGibson) +*/ + +// Dummy macros for when test framework is not present. +#ifndef COVERAGE +#define COVERAGE(a, b) +#endif + +#ifndef ASSERT_COVERED +#define ASSERT_COVERED(a) +#endif + +/* let's figure out if SSE is really available (unless disabled anyway) + (it isn't on non-x86/x86_64 platforms or even x86 without explicit SSE support) + => only use "#ifdef HANDMADE_MATH__USE_SSE" to check for SSE support below this block! */ +#ifndef HANDMADE_MATH_NO_SSE + +# ifdef _MSC_VER + /* MSVC supports SSE in amd64 mode or _M_IX86_FP >= 1 (2 means SSE2) */ +# if defined(_M_AMD64) || ( defined(_M_IX86_FP) && _M_IX86_FP >= 1 ) +# define HANDMADE_MATH__USE_SSE 1 +# endif +# else /* not MSVC, probably GCC, clang, icc or something that doesn't support SSE anyway */ +# ifdef __SSE__ /* they #define __SSE__ if it's supported */ +# define HANDMADE_MATH__USE_SSE 1 +# endif /* __SSE__ */ +# endif /* not _MSC_VER */ + +#endif /* #ifndef HANDMADE_MATH_NO_SSE */ + +#ifdef HANDMADE_MATH__USE_SSE +#include +#endif + +#ifndef HANDMADE_MATH_H +#define HANDMADE_MATH_H + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 8) +#pragma GCC diagnostic ignored "-Wmissing-braces" +#endif +#ifdef __clang__ +#pragma GCC diagnostic ignored "-Wgnu-anonymous-struct" +#endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define HMM_DEPRECATED(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) +#define HMM_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +#define HMM_DEPRECATED(msg) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define HMM_INLINE static inline +#define HMM_EXTERN extern + +#if !defined(HMM_SINF) || !defined(HMM_COSF) || !defined(HMM_TANF) || \ + !defined(HMM_SQRTF) || !defined(HMM_EXPF) || !defined(HMM_LOGF) || \ + !defined(HMM_ACOSF) || !defined(HMM_ATANF)|| !defined(HMM_ATAN2F) +#include +#endif + +#ifndef HMM_SINF +#define HMM_SINF sinf +#endif + +#ifndef HMM_COSF +#define HMM_COSF cosf +#endif + +#ifndef HMM_TANF +#define HMM_TANF tanf +#endif + +#ifndef HMM_SQRTF +#define HMM_SQRTF sqrtf +#endif + +#ifndef HMM_EXPF +#define HMM_EXPF expf +#endif + +#ifndef HMM_LOGF +#define HMM_LOGF logf +#endif + +#ifndef HMM_ACOSF +#define HMM_ACOSF acosf +#endif + +#ifndef HMM_ATANF +#define HMM_ATANF atanf +#endif + +#ifndef HMM_ATAN2F +#define HMM_ATAN2F atan2f +#endif + +#define HMM_PI32 3.14159265359f +#define HMM_PI 3.14159265358979323846 + +#define HMM_MIN(a, b) (a) > (b) ? (b) : (a) +#define HMM_MAX(a, b) (a) < (b) ? (b) : (a) +#define HMM_ABS(a) ((a) > 0 ? (a) : -(a)) +#define HMM_MOD(a, m) ((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m)) +#define HMM_SQUARE(x) ((x) * (x)) + +#ifndef HMM_PREFIX +#define HMM_PREFIX(name) HMM_##name +#endif + +typedef union hmm_vec2 +{ + struct + { + float X, Y; + }; + + struct + { + float U, V; + }; + + struct + { + float Left, Right; + }; + + struct + { + float Width, Height; + }; + + float Elements[2]; + +#ifdef __cplusplus + inline float &operator[](const int &Index) + { + return Elements[Index]; + } +#endif +} hmm_vec2; + +typedef union hmm_vec3 +{ + struct + { + float X, Y, Z; + }; + + struct + { + float U, V, W; + }; + + struct + { + float R, G, B; + }; + + struct + { + hmm_vec2 XY; + float Ignored0_; + }; + + struct + { + float Ignored1_; + hmm_vec2 YZ; + }; + + struct + { + hmm_vec2 UV; + float Ignored2_; + }; + + struct + { + float Ignored3_; + hmm_vec2 VW; + }; + + float Elements[3]; + +#ifdef __cplusplus + inline float &operator[](const int &Index) + { + return Elements[Index]; + } +#endif +} hmm_vec3; + +typedef union hmm_vec4 +{ + struct + { + union + { + hmm_vec3 XYZ; + struct + { + float X, Y, Z; + }; + }; + + float W; + }; + struct + { + union + { + hmm_vec3 RGB; + struct + { + float R, G, B; + }; + }; + + float A; + }; + + struct + { + hmm_vec2 XY; + float Ignored0_; + float Ignored1_; + }; + + struct + { + float Ignored2_; + hmm_vec2 YZ; + float Ignored3_; + }; + + struct + { + float Ignored4_; + float Ignored5_; + hmm_vec2 ZW; + }; + + float Elements[4]; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 InternalElementsSSE; +#endif + +#ifdef __cplusplus + inline float &operator[](const int &Index) + { + return Elements[Index]; + } +#endif +} hmm_vec4; + +typedef union hmm_mat4 +{ + float Elements[4][4]; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Columns[4]; + + HMM_DEPRECATED("Our matrices are column-major, so this was named incorrectly. Use Columns instead.") + __m128 Rows[4]; +#endif + +#ifdef __cplusplus + inline hmm_vec4 operator[](const int &Index) + { + float* col = Elements[Index]; + + hmm_vec4 result; + result.Elements[0] = col[0]; + result.Elements[1] = col[1]; + result.Elements[2] = col[2]; + result.Elements[3] = col[3]; + + return result; + } +#endif +} hmm_mat4; + +typedef union hmm_quaternion +{ + struct + { + union + { + hmm_vec3 XYZ; + struct + { + float X, Y, Z; + }; + }; + + float W; + }; + + float Elements[4]; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 InternalElementsSSE; +#endif +} hmm_quaternion; + +typedef signed int hmm_bool; + +typedef hmm_vec2 hmm_v2; +typedef hmm_vec3 hmm_v3; +typedef hmm_vec4 hmm_v4; +typedef hmm_mat4 hmm_m4; + + +/* + * Floating-point math functions + */ + +COVERAGE(HMM_SinF, 1) +HMM_INLINE float HMM_PREFIX(SinF)(float Radians) +{ + ASSERT_COVERED(HMM_SinF); + + float Result = HMM_SINF(Radians); + + return (Result); +} + +COVERAGE(HMM_CosF, 1) +HMM_INLINE float HMM_PREFIX(CosF)(float Radians) +{ + ASSERT_COVERED(HMM_CosF); + + float Result = HMM_COSF(Radians); + + return (Result); +} + +COVERAGE(HMM_TanF, 1) +HMM_INLINE float HMM_PREFIX(TanF)(float Radians) +{ + ASSERT_COVERED(HMM_TanF); + + float Result = HMM_TANF(Radians); + + return (Result); +} + +COVERAGE(HMM_ACosF, 1) +HMM_INLINE float HMM_PREFIX(ACosF)(float Radians) +{ + ASSERT_COVERED(HMM_ACosF); + + float Result = HMM_ACOSF(Radians); + + return (Result); +} + +COVERAGE(HMM_ATanF, 1) +HMM_INLINE float HMM_PREFIX(ATanF)(float Radians) +{ + ASSERT_COVERED(HMM_ATanF); + + float Result = HMM_ATANF(Radians); + + return (Result); +} + +COVERAGE(HMM_ATan2F, 1) +HMM_INLINE float HMM_PREFIX(ATan2F)(float Left, float Right) +{ + ASSERT_COVERED(HMM_ATan2F); + + float Result = HMM_ATAN2F(Left, Right); + + return (Result); +} + +COVERAGE(HMM_ExpF, 1) +HMM_INLINE float HMM_PREFIX(ExpF)(float Float) +{ + ASSERT_COVERED(HMM_ExpF); + + float Result = HMM_EXPF(Float); + + return (Result); +} + +COVERAGE(HMM_LogF, 1) +HMM_INLINE float HMM_PREFIX(LogF)(float Float) +{ + ASSERT_COVERED(HMM_LogF); + + float Result = HMM_LOGF(Float); + + return (Result); +} + +COVERAGE(HMM_SquareRootF, 1) +HMM_INLINE float HMM_PREFIX(SquareRootF)(float Float) +{ + ASSERT_COVERED(HMM_SquareRootF); + + float Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 In = _mm_set_ss(Float); + __m128 Out = _mm_sqrt_ss(In); + Result = _mm_cvtss_f32(Out); +#else + Result = HMM_SQRTF(Float); +#endif + + return(Result); +} + +COVERAGE(HMM_RSquareRootF, 1) +HMM_INLINE float HMM_PREFIX(RSquareRootF)(float Float) +{ + ASSERT_COVERED(HMM_RSquareRootF); + + float Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 In = _mm_set_ss(Float); + __m128 Out = _mm_rsqrt_ss(In); + Result = _mm_cvtss_f32(Out); +#else + Result = 1.0f/HMM_PREFIX(SquareRootF)(Float); +#endif + + return(Result); +} + +HMM_EXTERN float HMM_PREFIX(Power)(float Base, int Exponent); + +COVERAGE(HMM_PowerF, 1) +HMM_INLINE float HMM_PREFIX(PowerF)(float Base, float Exponent) +{ + ASSERT_COVERED(HMM_PowerF); + + float Result = HMM_EXPF(Exponent * HMM_LOGF(Base)); + + return (Result); +} + + +/* + * Utility functions + */ + +COVERAGE(HMM_ToRadians, 1) +HMM_INLINE float HMM_PREFIX(ToRadians)(float Degrees) +{ + ASSERT_COVERED(HMM_ToRadians); + + float Result = Degrees * (HMM_PI32 / 180.0f); + + return (Result); +} + +COVERAGE(HMM_Lerp, 1) +HMM_INLINE float HMM_PREFIX(Lerp)(float A, float Time, float B) +{ + ASSERT_COVERED(HMM_Lerp); + + float Result = (1.0f - Time) * A + Time * B; + + return (Result); +} + +COVERAGE(HMM_Clamp, 1) +HMM_INLINE float HMM_PREFIX(Clamp)(float Min, float Value, float Max) +{ + ASSERT_COVERED(HMM_Clamp); + + float Result = Value; + + if(Result < Min) + { + Result = Min; + } + + if(Result > Max) + { + Result = Max; + } + + return (Result); +} + + +/* + * Vector initialization + */ + +COVERAGE(HMM_Vec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Vec2)(float X, float Y) +{ + ASSERT_COVERED(HMM_Vec2); + + hmm_vec2 Result; + + Result.X = X; + Result.Y = Y; + + return (Result); +} + +COVERAGE(HMM_Vec2i, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Vec2i)(int X, int Y) +{ + ASSERT_COVERED(HMM_Vec2i); + + hmm_vec2 Result; + + Result.X = (float)X; + Result.Y = (float)Y; + + return (Result); +} + +COVERAGE(HMM_Vec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Vec3)(float X, float Y, float Z) +{ + ASSERT_COVERED(HMM_Vec3); + + hmm_vec3 Result; + + Result.X = X; + Result.Y = Y; + Result.Z = Z; + + return (Result); +} + +COVERAGE(HMM_Vec3i, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Vec3i)(int X, int Y, int Z) +{ + ASSERT_COVERED(HMM_Vec3i); + + hmm_vec3 Result; + + Result.X = (float)X; + Result.Y = (float)Y; + Result.Z = (float)Z; + + return (Result); +} + +COVERAGE(HMM_Vec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4)(float X, float Y, float Z, float W) +{ + ASSERT_COVERED(HMM_Vec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_setr_ps(X, Y, Z, W); +#else + Result.X = X; + Result.Y = Y; + Result.Z = Z; + Result.W = W; +#endif + + return (Result); +} + +COVERAGE(HMM_Vec4i, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4i)(int X, int Y, int Z, int W) +{ + ASSERT_COVERED(HMM_Vec4i); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_setr_ps((float)X, (float)Y, (float)Z, (float)W); +#else + Result.X = (float)X; + Result.Y = (float)Y; + Result.Z = (float)Z; + Result.W = (float)W; +#endif + + return (Result); +} + +COVERAGE(HMM_Vec4v, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Vec4v)(hmm_vec3 Vector, float W) +{ + ASSERT_COVERED(HMM_Vec4v); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_setr_ps(Vector.X, Vector.Y, Vector.Z, W); +#else + Result.XYZ = Vector; + Result.W = W; +#endif + + return (Result); +} + + +/* + * Binary vector operations + */ + +COVERAGE(HMM_AddVec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(AddVec2)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_AddVec2); + + hmm_vec2 Result; + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + + return (Result); +} + +COVERAGE(HMM_AddVec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(AddVec3)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_AddVec3); + + hmm_vec3 Result; + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + Result.Z = Left.Z + Right.Z; + + return (Result); +} + +COVERAGE(HMM_AddVec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(AddVec4)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_AddVec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_add_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + Result.Z = Left.Z + Right.Z; + Result.W = Left.W + Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_SubtractVec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(SubtractVec2)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_SubtractVec2); + + hmm_vec2 Result; + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + + return (Result); +} + +COVERAGE(HMM_SubtractVec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(SubtractVec3)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_SubtractVec3); + + hmm_vec3 Result; + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + Result.Z = Left.Z - Right.Z; + + return (Result); +} + +COVERAGE(HMM_SubtractVec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(SubtractVec4)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_SubtractVec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_sub_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + Result.Z = Left.Z - Right.Z; + Result.W = Left.W - Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(MultiplyVec2)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2); + + hmm_vec2 Result; + + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2f, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(MultiplyVec2f)(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2f); + + hmm_vec2 Result; + + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(MultiplyVec3)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3); + + hmm_vec3 Result; + + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + Result.Z = Left.Z * Right.Z; + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3f, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(MultiplyVec3f)(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3f); + + hmm_vec3 Result; + + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + Result.Z = Left.Z * Right; + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(MultiplyVec4)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + Result.Z = Left.Z * Right.Z; + Result.W = Left.W * Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4f, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(MultiplyVec4f)(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4f); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Scalar = _mm_set1_ps(Right); + Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Scalar); +#else + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + Result.Z = Left.Z * Right; + Result.W = Left.W * Right; +#endif + + return (Result); +} + +COVERAGE(HMM_DivideVec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(DivideVec2)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_DivideVec2); + + hmm_vec2 Result; + + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + + return (Result); +} + +COVERAGE(HMM_DivideVec2f, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(DivideVec2f)(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec2f); + + hmm_vec2 Result; + + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + + return (Result); +} + +COVERAGE(HMM_DivideVec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(DivideVec3)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_DivideVec3); + + hmm_vec3 Result; + + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + Result.Z = Left.Z / Right.Z; + + return (Result); +} + +COVERAGE(HMM_DivideVec3f, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(DivideVec3f)(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec3f); + + hmm_vec3 Result; + + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + Result.Z = Left.Z / Right; + + return (Result); +} + +COVERAGE(HMM_DivideVec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(DivideVec4)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_DivideVec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + Result.Z = Left.Z / Right.Z; + Result.W = Left.W / Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_DivideVec4f, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(DivideVec4f)(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec4f); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Scalar = _mm_set1_ps(Right); + Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Scalar); +#else + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + Result.Z = Left.Z / Right; + Result.W = Left.W / Right; +#endif + + return (Result); +} + +COVERAGE(HMM_EqualsVec2, 1) +HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec2)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_EqualsVec2); + + hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y); + + return (Result); +} + +COVERAGE(HMM_EqualsVec3, 1) +HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec3)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_EqualsVec3); + + hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z); + + return (Result); +} + +COVERAGE(HMM_EqualsVec4, 1) +HMM_INLINE hmm_bool HMM_PREFIX(EqualsVec4)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_EqualsVec4); + + hmm_bool Result = (Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z && Left.W == Right.W); + + return (Result); +} + +COVERAGE(HMM_DotVec2, 1) +HMM_INLINE float HMM_PREFIX(DotVec2)(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec2); + + float Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y); + + return (Result); +} + +COVERAGE(HMM_DotVec3, 1) +HMM_INLINE float HMM_PREFIX(DotVec3)(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec3); + + float Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); + + return (Result); +} + +COVERAGE(HMM_DotVec4, 1) +HMM_INLINE float HMM_PREFIX(DotVec4)(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec4); + + float Result; + + // NOTE(zak): IN the future if we wanna check what version SSE is support + // we can use _mm_dp_ps (4.3) but for now we will use the old way. + // Or a r = _mm_mul_ps(v1, v2), r = _mm_hadd_ps(r, r), r = _mm_hadd_ps(r, r) for SSE3 +#ifdef HANDMADE_MATH__USE_SSE + __m128 SSEResultOne = _mm_mul_ps(VecOne.InternalElementsSSE, VecTwo.InternalElementsSSE); + __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); + SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); + SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); + SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); + _mm_store_ss(&Result, SSEResultOne); +#else + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z) + (VecOne.W * VecTwo.W); +#endif + + return (Result); +} + +COVERAGE(HMM_Cross, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Cross)(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + ASSERT_COVERED(HMM_Cross); + + hmm_vec3 Result; + + Result.X = (VecOne.Y * VecTwo.Z) - (VecOne.Z * VecTwo.Y); + Result.Y = (VecOne.Z * VecTwo.X) - (VecOne.X * VecTwo.Z); + Result.Z = (VecOne.X * VecTwo.Y) - (VecOne.Y * VecTwo.X); + + return (Result); +} + + +/* + * Unary vector operations + */ + +COVERAGE(HMM_LengthSquaredVec2, 1) +HMM_INLINE float HMM_PREFIX(LengthSquaredVec2)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec2); + + float Result = HMM_PREFIX(DotVec2)(A, A); + + return (Result); +} + +COVERAGE(HMM_LengthSquaredVec3, 1) +HMM_INLINE float HMM_PREFIX(LengthSquaredVec3)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec3); + + float Result = HMM_PREFIX(DotVec3)(A, A); + + return (Result); +} + +COVERAGE(HMM_LengthSquaredVec4, 1) +HMM_INLINE float HMM_PREFIX(LengthSquaredVec4)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec4); + + float Result = HMM_PREFIX(DotVec4)(A, A); + + return (Result); +} + +COVERAGE(HMM_LengthVec2, 1) +HMM_INLINE float HMM_PREFIX(LengthVec2)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_LengthVec2); + + float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec2)(A)); + + return (Result); +} + +COVERAGE(HMM_LengthVec3, 1) +HMM_INLINE float HMM_PREFIX(LengthVec3)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_LengthVec3); + + float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec3)(A)); + + return (Result); +} + +COVERAGE(HMM_LengthVec4, 1) +HMM_INLINE float HMM_PREFIX(LengthVec4)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_LengthVec4); + + float Result = HMM_PREFIX(SquareRootF)(HMM_PREFIX(LengthSquaredVec4)(A)); + + return(Result); +} + +COVERAGE(HMM_NormalizeVec2, 2) +HMM_INLINE hmm_vec2 HMM_PREFIX(NormalizeVec2)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_NormalizeVec2); + + hmm_vec2 Result = {0}; + + float VectorLength = HMM_PREFIX(LengthVec2)(A); + + /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ + if (VectorLength != 0.0f) + { + ASSERT_COVERED(HMM_NormalizeVec2); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + } + + return (Result); +} + +COVERAGE(HMM_NormalizeVec3, 2) +HMM_INLINE hmm_vec3 HMM_PREFIX(NormalizeVec3)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_NormalizeVec3); + + hmm_vec3 Result = {0}; + + float VectorLength = HMM_PREFIX(LengthVec3)(A); + + /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ + if (VectorLength != 0.0f) + { + ASSERT_COVERED(HMM_NormalizeVec3); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + Result.Z = A.Z * (1.0f / VectorLength); + } + + return (Result); +} + +COVERAGE(HMM_NormalizeVec4, 2) +HMM_INLINE hmm_vec4 HMM_PREFIX(NormalizeVec4)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_NormalizeVec4); + + hmm_vec4 Result = {0}; + + float VectorLength = HMM_PREFIX(LengthVec4)(A); + + /* NOTE(kiljacken): We need a zero check to not divide-by-zero */ + if (VectorLength != 0.0f) + { + ASSERT_COVERED(HMM_NormalizeVec4); + + float Multiplier = 1.0f / VectorLength; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 SSEMultiplier = _mm_set1_ps(Multiplier); + Result.InternalElementsSSE = _mm_mul_ps(A.InternalElementsSSE, SSEMultiplier); +#else + Result.X = A.X * Multiplier; + Result.Y = A.Y * Multiplier; + Result.Z = A.Z * Multiplier; + Result.W = A.W * Multiplier; +#endif + } + + return (Result); +} + +COVERAGE(HMM_FastNormalizeVec2, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(FastNormalizeVec2)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec2); + + return HMM_PREFIX(MultiplyVec2f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec2)(A, A))); +} + +COVERAGE(HMM_FastNormalizeVec3, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(FastNormalizeVec3)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec3); + + return HMM_PREFIX(MultiplyVec3f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec3)(A, A))); +} + +COVERAGE(HMM_FastNormalizeVec4, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(FastNormalizeVec4)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec4); + + return HMM_PREFIX(MultiplyVec4f)(A, HMM_PREFIX(RSquareRootF)(HMM_PREFIX(DotVec4)(A, A))); +} + + +/* + * SSE stuff + */ + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_LinearCombineSSE, 1) +HMM_INLINE __m128 HMM_PREFIX(LinearCombineSSE)(__m128 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_LinearCombineSSE); + + __m128 Result; + Result = _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x00), Right.Columns[0]); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0x55), Right.Columns[1])); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xaa), Right.Columns[2])); + Result = _mm_add_ps(Result, _mm_mul_ps(_mm_shuffle_ps(Left, Left, 0xff), Right.Columns[3])); + + return (Result); +} +#endif + + +/* + * Matrix functions + */ + +COVERAGE(HMM_Mat4, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Mat4)(void) +{ + ASSERT_COVERED(HMM_Mat4); + + hmm_mat4 Result = {0}; + + return (Result); +} + +COVERAGE(HMM_Mat4d, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Mat4d)(float Diagonal) +{ + ASSERT_COVERED(HMM_Mat4d); + + hmm_mat4 Result = HMM_PREFIX(Mat4)(); + + Result.Elements[0][0] = Diagonal; + Result.Elements[1][1] = Diagonal; + Result.Elements[2][2] = Diagonal; + Result.Elements[3][3] = Diagonal; + + return (Result); +} + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_Transpose, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix) +{ + ASSERT_COVERED(HMM_Transpose); + + hmm_mat4 Result = Matrix; + + _MM_TRANSPOSE4_PS(Result.Columns[0], Result.Columns[1], Result.Columns[2], Result.Columns[3]); + + return (Result); +} +#else +HMM_EXTERN hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix); +#endif + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_AddMat4, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_AddMat4); + + hmm_mat4 Result; + + Result.Columns[0] = _mm_add_ps(Left.Columns[0], Right.Columns[0]); + Result.Columns[1] = _mm_add_ps(Left.Columns[1], Right.Columns[1]); + Result.Columns[2] = _mm_add_ps(Left.Columns[2], Right.Columns[2]); + Result.Columns[3] = _mm_add_ps(Left.Columns[3], Right.Columns[3]); + + return (Result); +} +#else +HMM_EXTERN hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right); +#endif + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_SubtractMat4, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_SubtractMat4); + + hmm_mat4 Result; + + Result.Columns[0] = _mm_sub_ps(Left.Columns[0], Right.Columns[0]); + Result.Columns[1] = _mm_sub_ps(Left.Columns[1], Right.Columns[1]); + Result.Columns[2] = _mm_sub_ps(Left.Columns[2], Right.Columns[2]); + Result.Columns[3] = _mm_sub_ps(Left.Columns[3], Right.Columns[3]); + + return (Result); +} +#else +HMM_EXTERN hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right); +#endif + +HMM_EXTERN hmm_mat4 HMM_PREFIX(MultiplyMat4)(hmm_mat4 Left, hmm_mat4 Right); + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_MultiplyMat4f, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar) +{ + ASSERT_COVERED(HMM_MultiplyMat4f); + + hmm_mat4 Result; + + __m128 SSEScalar = _mm_set1_ps(Scalar); + Result.Columns[0] = _mm_mul_ps(Matrix.Columns[0], SSEScalar); + Result.Columns[1] = _mm_mul_ps(Matrix.Columns[1], SSEScalar); + Result.Columns[2] = _mm_mul_ps(Matrix.Columns[2], SSEScalar); + Result.Columns[3] = _mm_mul_ps(Matrix.Columns[3], SSEScalar); + + return (Result); +} +#else +HMM_EXTERN hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar); +#endif + +HMM_EXTERN hmm_vec4 HMM_PREFIX(MultiplyMat4ByVec4)(hmm_mat4 Matrix, hmm_vec4 Vector); + +#ifdef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_DivideMat4f, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar) +{ + ASSERT_COVERED(HMM_DivideMat4f); + + hmm_mat4 Result; + + __m128 SSEScalar = _mm_set1_ps(Scalar); + Result.Columns[0] = _mm_div_ps(Matrix.Columns[0], SSEScalar); + Result.Columns[1] = _mm_div_ps(Matrix.Columns[1], SSEScalar); + Result.Columns[2] = _mm_div_ps(Matrix.Columns[2], SSEScalar); + Result.Columns[3] = _mm_div_ps(Matrix.Columns[3], SSEScalar); + + return (Result); +} +#else +HMM_EXTERN hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar); +#endif + + +/* + * Common graphics transformations + */ + +COVERAGE(HMM_Orthographic, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Orthographic)(float Left, float Right, float Bottom, float Top, float Near, float Far) +{ + ASSERT_COVERED(HMM_Orthographic); + + hmm_mat4 Result = HMM_PREFIX(Mat4)(); + + Result.Elements[0][0] = 2.0f / (Right - Left); + Result.Elements[1][1] = 2.0f / (Top - Bottom); + Result.Elements[2][2] = 2.0f / (Near - Far); + Result.Elements[3][3] = 1.0f; + + Result.Elements[3][0] = (Left + Right) / (Left - Right); + Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top); + Result.Elements[3][2] = (Far + Near) / (Near - Far); + + return (Result); +} + +COVERAGE(HMM_Perspective, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Perspective)(float FOV, float AspectRatio, float Near, float Far) +{ + ASSERT_COVERED(HMM_Perspective); + + hmm_mat4 Result = HMM_PREFIX(Mat4)(); + + // See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml + + float Cotangent = 1.0f / HMM_PREFIX(TanF)(FOV * (HMM_PI32 / 360.0f)); + + Result.Elements[0][0] = Cotangent / AspectRatio; + Result.Elements[1][1] = Cotangent; + Result.Elements[2][3] = -1.0f; + Result.Elements[2][2] = (Near + Far) / (Near - Far); + Result.Elements[3][2] = (2.0f * Near * Far) / (Near - Far); + Result.Elements[3][3] = 0.0f; + + return (Result); +} + +COVERAGE(HMM_Translate, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Translate)(hmm_vec3 Translation) +{ + ASSERT_COVERED(HMM_Translate); + + hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); + + Result.Elements[3][0] = Translation.X; + Result.Elements[3][1] = Translation.Y; + Result.Elements[3][2] = Translation.Z; + + return (Result); +} + +HMM_EXTERN hmm_mat4 HMM_PREFIX(Rotate)(float Angle, hmm_vec3 Axis); + +COVERAGE(HMM_Scale, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Scale)(hmm_vec3 Scale) +{ + ASSERT_COVERED(HMM_Scale); + + hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); + + Result.Elements[0][0] = Scale.X; + Result.Elements[1][1] = Scale.Y; + Result.Elements[2][2] = Scale.Z; + + return (Result); +} + +HMM_EXTERN hmm_mat4 HMM_PREFIX(LookAt)(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up); + + +/* + * Quaternion operations + */ + +COVERAGE(HMM_Quaternion, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Quaternion)(float X, float Y, float Z, float W) +{ + ASSERT_COVERED(HMM_Quaternion); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_setr_ps(X, Y, Z, W); +#else + Result.X = X; + Result.Y = Y; + Result.Z = Z; + Result.W = W; +#endif + + return (Result); +} + +COVERAGE(HMM_QuaternionV4, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(QuaternionV4)(hmm_vec4 Vector) +{ + ASSERT_COVERED(HMM_QuaternionV4); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = Vector.InternalElementsSSE; +#else + Result.X = Vector.X; + Result.Y = Vector.Y; + Result.Z = Vector.Z; + Result.W = Vector.W; +#endif + + return (Result); +} + +COVERAGE(HMM_AddQuaternion, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(AddQuaternion)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_AddQuaternion); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_add_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + Result.Z = Left.Z + Right.Z; + Result.W = Left.W + Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_SubtractQuaternion, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(SubtractQuaternion)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_SubtractQuaternion); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = _mm_sub_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); +#else + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + Result.Z = Left.Z - Right.Z; + Result.W = Left.W - Right.W; +#endif + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternion, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(MultiplyQuaternion)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternion); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(0, 0, 0, 0)), _mm_setr_ps(0.f, -0.f, 0.f, -0.f)); + __m128 SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(0, 1, 2, 3)); + __m128 SSEResultThree = _mm_mul_ps(SSEResultTwo, SSEResultOne); + + SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(1, 1, 1, 1)) , _mm_setr_ps(0.f, 0.f, -0.f, -0.f)); + SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(1, 0, 3, 2)); + SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); + + SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(2, 2, 2, 2)), _mm_setr_ps(-0.f, 0.f, 0.f, -0.f)); + SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(2, 3, 0, 1)); + SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); + + SSEResultOne = _mm_shuffle_ps(Left.InternalElementsSSE, Left.InternalElementsSSE, _MM_SHUFFLE(3, 3, 3, 3)); + SSEResultTwo = _mm_shuffle_ps(Right.InternalElementsSSE, Right.InternalElementsSSE, _MM_SHUFFLE(3, 2, 1, 0)); + Result.InternalElementsSSE = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); +#else + Result.X = (Left.X * Right.W) + (Left.Y * Right.Z) - (Left.Z * Right.Y) + (Left.W * Right.X); + Result.Y = (-Left.X * Right.Z) + (Left.Y * Right.W) + (Left.Z * Right.X) + (Left.W * Right.Y); + Result.Z = (Left.X * Right.Y) - (Left.Y * Right.X) + (Left.Z * Right.W) + (Left.W * Right.Z); + Result.W = (-Left.X * Right.X) - (Left.Y * Right.Y) - (Left.Z * Right.Z) + (Left.W * Right.W); +#endif + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionF, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(MultiplyQuaternionF)(hmm_quaternion Left, float Multiplicative) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionF); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Scalar = _mm_set1_ps(Multiplicative); + Result.InternalElementsSSE = _mm_mul_ps(Left.InternalElementsSSE, Scalar); +#else + Result.X = Left.X * Multiplicative; + Result.Y = Left.Y * Multiplicative; + Result.Z = Left.Z * Multiplicative; + Result.W = Left.W * Multiplicative; +#endif + + return (Result); +} + +COVERAGE(HMM_DivideQuaternionF, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(DivideQuaternionF)(hmm_quaternion Left, float Dividend) +{ + ASSERT_COVERED(HMM_DivideQuaternionF); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 Scalar = _mm_set1_ps(Dividend); + Result.InternalElementsSSE = _mm_div_ps(Left.InternalElementsSSE, Scalar); +#else + Result.X = Left.X / Dividend; + Result.Y = Left.Y / Dividend; + Result.Z = Left.Z / Dividend; + Result.W = Left.W / Dividend; +#endif + + return (Result); +} + +HMM_EXTERN hmm_quaternion HMM_PREFIX(InverseQuaternion)(hmm_quaternion Left); + +COVERAGE(HMM_DotQuaternion, 1) +HMM_INLINE float HMM_PREFIX(DotQuaternion)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_DotQuaternion); + + float Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 SSEResultOne = _mm_mul_ps(Left.InternalElementsSSE, Right.InternalElementsSSE); + __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); + SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); + SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); + SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); + _mm_store_ss(&Result, SSEResultOne); +#else + Result = (Left.X * Right.X) + (Left.Y * Right.Y) + (Left.Z * Right.Z) + (Left.W * Right.W); +#endif + + return (Result); +} + +COVERAGE(HMM_NormalizeQuaternion, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(NormalizeQuaternion)(hmm_quaternion Left) +{ + ASSERT_COVERED(HMM_NormalizeQuaternion); + + hmm_quaternion Result; + + float Length = HMM_PREFIX(SquareRootF)(HMM_PREFIX(DotQuaternion)(Left, Left)); + Result = HMM_PREFIX(DivideQuaternionF)(Left, Length); + + return (Result); +} + +COVERAGE(HMM_NLerp, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(NLerp)(hmm_quaternion Left, float Time, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_NLerp); + + hmm_quaternion Result; + +#ifdef HANDMADE_MATH__USE_SSE + __m128 ScalarLeft = _mm_set1_ps(1.0f - Time); + __m128 ScalarRight = _mm_set1_ps(Time); + __m128 SSEResultOne = _mm_mul_ps(Left.InternalElementsSSE, ScalarLeft); + __m128 SSEResultTwo = _mm_mul_ps(Right.InternalElementsSSE, ScalarRight); + Result.InternalElementsSSE = _mm_add_ps(SSEResultOne, SSEResultTwo); +#else + Result.X = HMM_PREFIX(Lerp)(Left.X, Time, Right.X); + Result.Y = HMM_PREFIX(Lerp)(Left.Y, Time, Right.Y); + Result.Z = HMM_PREFIX(Lerp)(Left.Z, Time, Right.Z); + Result.W = HMM_PREFIX(Lerp)(Left.W, Time, Right.W); +#endif + Result = HMM_PREFIX(NormalizeQuaternion)(Result); + + return (Result); +} + +HMM_EXTERN hmm_quaternion HMM_PREFIX(Slerp)(hmm_quaternion Left, float Time, hmm_quaternion Right); +HMM_EXTERN hmm_mat4 HMM_PREFIX(QuaternionToMat4)(hmm_quaternion Left); +HMM_EXTERN hmm_quaternion HMM_PREFIX(Mat4ToQuaternion)(hmm_mat4 Left); +HMM_EXTERN hmm_quaternion HMM_PREFIX(QuaternionFromAxisAngle)(hmm_vec3 Axis, float AngleOfRotation); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +COVERAGE(HMM_LengthVec2CPP, 1) +HMM_INLINE float HMM_PREFIX(Length)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_LengthVec2CPP); + + float Result = HMM_PREFIX(LengthVec2)(A); + + return (Result); +} + +COVERAGE(HMM_LengthVec3CPP, 1) +HMM_INLINE float HMM_PREFIX(Length)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_LengthVec3CPP); + + float Result = HMM_PREFIX(LengthVec3)(A); + + return (Result); +} + +COVERAGE(HMM_LengthVec4CPP, 1) +HMM_INLINE float HMM_PREFIX(Length)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_LengthVec4CPP); + + float Result = HMM_PREFIX(LengthVec4)(A); + + return (Result); +} + +COVERAGE(HMM_LengthSquaredVec2CPP, 1) +HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec2CPP); + + float Result = HMM_PREFIX(LengthSquaredVec2)(A); + + return (Result); +} + +COVERAGE(HMM_LengthSquaredVec3CPP, 1) +HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec3CPP); + + float Result = HMM_PREFIX(LengthSquaredVec3)(A); + + return (Result); +} + +COVERAGE(HMM_LengthSquaredVec4CPP, 1) +HMM_INLINE float HMM_PREFIX(LengthSquared)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_LengthSquaredVec4CPP); + + float Result = HMM_PREFIX(LengthSquaredVec4)(A); + + return (Result); +} + +COVERAGE(HMM_NormalizeVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Normalize)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_NormalizeVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(NormalizeVec2)(A); + + return (Result); +} + +COVERAGE(HMM_NormalizeVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Normalize)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_NormalizeVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(NormalizeVec3)(A); + + return (Result); +} + +COVERAGE(HMM_NormalizeVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Normalize)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_NormalizeVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(NormalizeVec4)(A); + + return (Result); +} + +COVERAGE(HMM_FastNormalizeVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(FastNormalize)(hmm_vec2 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(FastNormalizeVec2)(A); + + return (Result); +} + +COVERAGE(HMM_FastNormalizeVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(FastNormalize)(hmm_vec3 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(FastNormalizeVec3)(A); + + return (Result); +} + +COVERAGE(HMM_FastNormalizeVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(FastNormalize)(hmm_vec4 A) +{ + ASSERT_COVERED(HMM_FastNormalizeVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(FastNormalizeVec4)(A); + + return (Result); +} + +COVERAGE(HMM_NormalizeQuaternionCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Normalize)(hmm_quaternion A) +{ + ASSERT_COVERED(HMM_NormalizeQuaternionCPP); + + hmm_quaternion Result = HMM_PREFIX(NormalizeQuaternion)(A); + + return (Result); +} + +COVERAGE(HMM_DotVec2CPP, 1) +HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec2CPP); + + float Result = HMM_PREFIX(DotVec2)(VecOne, VecTwo); + + return (Result); +} + +COVERAGE(HMM_DotVec3CPP, 1) +HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec3CPP); + + float Result = HMM_PREFIX(DotVec3)(VecOne, VecTwo); + + return (Result); +} + +COVERAGE(HMM_DotVec4CPP, 1) +HMM_INLINE float HMM_PREFIX(Dot)(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + ASSERT_COVERED(HMM_DotVec4CPP); + + float Result = HMM_PREFIX(DotVec4)(VecOne, VecTwo); + + return (Result); +} + +COVERAGE(HMM_DotQuaternionCPP, 1) +HMM_INLINE float HMM_PREFIX(Dot)(hmm_quaternion QuatOne, hmm_quaternion QuatTwo) +{ + ASSERT_COVERED(HMM_DotQuaternionCPP); + + float Result = HMM_PREFIX(DotQuaternion)(QuatOne, QuatTwo); + + return (Result); +} + +COVERAGE(HMM_AddVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Add)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_AddVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(AddVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Add)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_AddVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(AddVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Add)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_AddVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(AddVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddMat4CPP, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Add)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_AddMat4CPP); + + hmm_mat4 Result = HMM_PREFIX(AddMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddQuaternionCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Add)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_AddQuaternionCPP); + + hmm_quaternion Result = HMM_PREFIX(AddQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Subtract)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_SubtractVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(SubtractVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Subtract)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_SubtractVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(SubtractVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Subtract)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_SubtractVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(SubtractVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractMat4CPP, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Subtract)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_SubtractMat4CPP); + + hmm_mat4 Result = HMM_PREFIX(SubtractMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractQuaternionCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Subtract)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_SubtractQuaternionCPP); + + hmm_quaternion Result = HMM_PREFIX(SubtractQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Multiply)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(MultiplyVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2fCPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Multiply)(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2fCPP); + + hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Multiply)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(MultiplyVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3fCPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Multiply)(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3fCPP); + + hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(MultiplyVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4fCPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4fCPP); + + hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4CPP, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Multiply)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4CPP); + + hmm_mat4 Result = HMM_PREFIX(MultiplyMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4fCPP, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Multiply)(hmm_mat4 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4fCPP); + + hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4ByVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Multiply)(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + ASSERT_COVERED(HMM_MultiplyMat4ByVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(MultiplyMat4ByVec4)(Matrix, Vector); + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Multiply)(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionCPP); + + hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionFCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Multiply)(hmm_quaternion Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionFCPP); + + hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec2CPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Divide)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_DivideVec2CPP); + + hmm_vec2 Result = HMM_PREFIX(DivideVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec2fCPP, 1) +HMM_INLINE hmm_vec2 HMM_PREFIX(Divide)(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec2fCPP); + + hmm_vec2 Result = HMM_PREFIX(DivideVec2f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec3CPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Divide)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_DivideVec3CPP); + + hmm_vec3 Result = HMM_PREFIX(DivideVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec3fCPP, 1) +HMM_INLINE hmm_vec3 HMM_PREFIX(Divide)(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec3fCPP); + + hmm_vec3 Result = HMM_PREFIX(DivideVec3f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec4CPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Divide)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_DivideVec4CPP); + + hmm_vec4 Result = HMM_PREFIX(DivideVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec4fCPP, 1) +HMM_INLINE hmm_vec4 HMM_PREFIX(Divide)(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec4fCPP); + + hmm_vec4 Result = HMM_PREFIX(DivideVec4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideMat4fCPP, 1) +HMM_INLINE hmm_mat4 HMM_PREFIX(Divide)(hmm_mat4 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideMat4fCPP); + + hmm_mat4 Result = HMM_PREFIX(DivideMat4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideQuaternionFCPP, 1) +HMM_INLINE hmm_quaternion HMM_PREFIX(Divide)(hmm_quaternion Left, float Right) +{ + ASSERT_COVERED(HMM_DivideQuaternionFCPP); + + hmm_quaternion Result = HMM_PREFIX(DivideQuaternionF)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_EqualsVec2CPP, 1) +HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_EqualsVec2CPP); + + hmm_bool Result = HMM_PREFIX(EqualsVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_EqualsVec3CPP, 1) +HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_EqualsVec3CPP); + + hmm_bool Result = HMM_PREFIX(EqualsVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_EqualsVec4CPP, 1) +HMM_INLINE hmm_bool HMM_PREFIX(Equals)(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_EqualsVec4CPP); + + hmm_bool Result = HMM_PREFIX(EqualsVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec2Op, 1) +HMM_INLINE hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_AddVec2Op); + + hmm_vec2 Result = HMM_PREFIX(AddVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec3Op, 1) +HMM_INLINE hmm_vec3 operator+(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_AddVec3Op); + + hmm_vec3 Result = HMM_PREFIX(AddVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec4Op, 1) +HMM_INLINE hmm_vec4 operator+(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_AddVec4Op); + + hmm_vec4 Result = HMM_PREFIX(AddVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddMat4Op, 1) +HMM_INLINE hmm_mat4 operator+(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_AddMat4Op); + + hmm_mat4 Result = HMM_PREFIX(AddMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddQuaternionOp, 1) +HMM_INLINE hmm_quaternion operator+(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_AddQuaternionOp); + + hmm_quaternion Result = HMM_PREFIX(AddQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec2Op, 1) +HMM_INLINE hmm_vec2 operator-(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_SubtractVec2Op); + + hmm_vec2 Result = HMM_PREFIX(SubtractVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec3Op, 1) +HMM_INLINE hmm_vec3 operator-(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_SubtractVec3Op); + + hmm_vec3 Result = HMM_PREFIX(SubtractVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractVec4Op, 1) +HMM_INLINE hmm_vec4 operator-(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_SubtractVec4Op); + + hmm_vec4 Result = HMM_PREFIX(SubtractVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractMat4Op, 1) +HMM_INLINE hmm_mat4 operator-(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_SubtractMat4Op); + + hmm_mat4 Result = HMM_PREFIX(SubtractMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_SubtractQuaternionOp, 1) +HMM_INLINE hmm_quaternion operator-(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_SubtractQuaternionOp); + + hmm_quaternion Result = HMM_PREFIX(SubtractQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2Op, 1) +HMM_INLINE hmm_vec2 operator*(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2Op); + + hmm_vec2 Result = HMM_PREFIX(MultiplyVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3Op, 1) +HMM_INLINE hmm_vec3 operator*(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3Op); + + hmm_vec3 Result = HMM_PREFIX(MultiplyVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4Op, 1) +HMM_INLINE hmm_vec4 operator*(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4Op); + + hmm_vec4 Result = HMM_PREFIX(MultiplyVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4Op, 1) +HMM_INLINE hmm_mat4 operator*(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4Op); + + hmm_mat4 Result = HMM_PREFIX(MultiplyMat4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionOp, 1) +HMM_INLINE hmm_quaternion operator*(hmm_quaternion Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionOp); + + hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternion)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2fOp, 1) +HMM_INLINE hmm_vec2 operator*(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2fOp); + + hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3fOp, 1) +HMM_INLINE hmm_vec3 operator*(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3fOp); + + hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4fOp, 1) +HMM_INLINE hmm_vec4 operator*(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4fOp); + + hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4fOp, 1) +HMM_INLINE hmm_mat4 operator*(hmm_mat4 Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4fOp); + + hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionFOp, 1) +HMM_INLINE hmm_quaternion operator*(hmm_quaternion Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionFOp); + + hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec2fOpLeft, 1) +HMM_INLINE hmm_vec2 operator*(float Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2fOpLeft); + + hmm_vec2 Result = HMM_PREFIX(MultiplyVec2f)(Right, Left); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec3fOpLeft, 1) +HMM_INLINE hmm_vec3 operator*(float Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3fOpLeft); + + hmm_vec3 Result = HMM_PREFIX(MultiplyVec3f)(Right, Left); + + return (Result); +} + +COVERAGE(HMM_MultiplyVec4fOpLeft, 1) +HMM_INLINE hmm_vec4 operator*(float Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4fOpLeft); + + hmm_vec4 Result = HMM_PREFIX(MultiplyVec4f)(Right, Left); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4fOpLeft, 1) +HMM_INLINE hmm_mat4 operator*(float Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4fOpLeft); + + hmm_mat4 Result = HMM_PREFIX(MultiplyMat4f)(Right, Left); + + return (Result); +} + +COVERAGE(HMM_MultiplyQuaternionFOpLeft, 1) +HMM_INLINE hmm_quaternion operator*(float Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionFOpLeft); + + hmm_quaternion Result = HMM_PREFIX(MultiplyQuaternionF)(Right, Left); + + return (Result); +} + +COVERAGE(HMM_MultiplyMat4ByVec4Op, 1) +HMM_INLINE hmm_vec4 operator*(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + ASSERT_COVERED(HMM_MultiplyMat4ByVec4Op); + + hmm_vec4 Result = HMM_PREFIX(MultiplyMat4ByVec4)(Matrix, Vector); + + return (Result); +} + +COVERAGE(HMM_DivideVec2Op, 1) +HMM_INLINE hmm_vec2 operator/(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_DivideVec2Op); + + hmm_vec2 Result = HMM_PREFIX(DivideVec2)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec3Op, 1) +HMM_INLINE hmm_vec3 operator/(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_DivideVec3Op); + + hmm_vec3 Result = HMM_PREFIX(DivideVec3)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec4Op, 1) +HMM_INLINE hmm_vec4 operator/(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_DivideVec4Op); + + hmm_vec4 Result = HMM_PREFIX(DivideVec4)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec2fOp, 1) +HMM_INLINE hmm_vec2 operator/(hmm_vec2 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec2fOp); + + hmm_vec2 Result = HMM_PREFIX(DivideVec2f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec3fOp, 1) +HMM_INLINE hmm_vec3 operator/(hmm_vec3 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec3fOp); + + hmm_vec3 Result = HMM_PREFIX(DivideVec3f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideVec4fOp, 1) +HMM_INLINE hmm_vec4 operator/(hmm_vec4 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec4fOp); + + hmm_vec4 Result = HMM_PREFIX(DivideVec4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideMat4fOp, 1) +HMM_INLINE hmm_mat4 operator/(hmm_mat4 Left, float Right) +{ + ASSERT_COVERED(HMM_DivideMat4fOp); + + hmm_mat4 Result = HMM_PREFIX(DivideMat4f)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_DivideQuaternionFOp, 1) +HMM_INLINE hmm_quaternion operator/(hmm_quaternion Left, float Right) +{ + ASSERT_COVERED(HMM_DivideQuaternionFOp); + + hmm_quaternion Result = HMM_PREFIX(DivideQuaternionF)(Left, Right); + + return (Result); +} + +COVERAGE(HMM_AddVec2Assign, 1) +HMM_INLINE hmm_vec2 &operator+=(hmm_vec2 &Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_AddVec2Assign); + + return (Left = Left + Right); +} + +COVERAGE(HMM_AddVec3Assign, 1) +HMM_INLINE hmm_vec3 &operator+=(hmm_vec3 &Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_AddVec3Assign); + + return (Left = Left + Right); +} + +COVERAGE(HMM_AddVec4Assign, 1) +HMM_INLINE hmm_vec4 &operator+=(hmm_vec4 &Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_AddVec4Assign); + + return (Left = Left + Right); +} + +COVERAGE(HMM_AddMat4Assign, 1) +HMM_INLINE hmm_mat4 &operator+=(hmm_mat4 &Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_AddMat4Assign); + + return (Left = Left + Right); +} + +COVERAGE(HMM_AddQuaternionAssign, 1) +HMM_INLINE hmm_quaternion &operator+=(hmm_quaternion &Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_AddQuaternionAssign); + + return (Left = Left + Right); +} + +COVERAGE(HMM_SubtractVec2Assign, 1) +HMM_INLINE hmm_vec2 &operator-=(hmm_vec2 &Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_SubtractVec2Assign); + + return (Left = Left - Right); +} + +COVERAGE(HMM_SubtractVec3Assign, 1) +HMM_INLINE hmm_vec3 &operator-=(hmm_vec3 &Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_SubtractVec3Assign); + + return (Left = Left - Right); +} + +COVERAGE(HMM_SubtractVec4Assign, 1) +HMM_INLINE hmm_vec4 &operator-=(hmm_vec4 &Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_SubtractVec4Assign); + + return (Left = Left - Right); +} + +COVERAGE(HMM_SubtractMat4Assign, 1) +HMM_INLINE hmm_mat4 &operator-=(hmm_mat4 &Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_SubtractMat4Assign); + + return (Left = Left - Right); +} + +COVERAGE(HMM_SubtractQuaternionAssign, 1) +HMM_INLINE hmm_quaternion &operator-=(hmm_quaternion &Left, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_SubtractQuaternionAssign); + + return (Left = Left - Right); +} + +COVERAGE(HMM_MultiplyVec2Assign, 1) +HMM_INLINE hmm_vec2 &operator*=(hmm_vec2 &Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2Assign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyVec3Assign, 1) +HMM_INLINE hmm_vec3 &operator*=(hmm_vec3 &Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3Assign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyVec4Assign, 1) +HMM_INLINE hmm_vec4 &operator*=(hmm_vec4 &Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4Assign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyVec2fAssign, 1) +HMM_INLINE hmm_vec2 &operator*=(hmm_vec2 &Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec2fAssign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyVec3fAssign, 1) +HMM_INLINE hmm_vec3 &operator*=(hmm_vec3 &Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec3fAssign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyVec4fAssign, 1) +HMM_INLINE hmm_vec4 &operator*=(hmm_vec4 &Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyVec4fAssign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyMat4fAssign, 1) +HMM_INLINE hmm_mat4 &operator*=(hmm_mat4 &Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4fAssign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_MultiplyQuaternionFAssign, 1) +HMM_INLINE hmm_quaternion &operator*=(hmm_quaternion &Left, float Right) +{ + ASSERT_COVERED(HMM_MultiplyQuaternionFAssign); + + return (Left = Left * Right); +} + +COVERAGE(HMM_DivideVec2Assign, 1) +HMM_INLINE hmm_vec2 &operator/=(hmm_vec2 &Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_DivideVec2Assign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideVec3Assign, 1) +HMM_INLINE hmm_vec3 &operator/=(hmm_vec3 &Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_DivideVec3Assign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideVec4Assign, 1) +HMM_INLINE hmm_vec4 &operator/=(hmm_vec4 &Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_DivideVec4Assign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideVec2fAssign, 1) +HMM_INLINE hmm_vec2 &operator/=(hmm_vec2 &Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec2fAssign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideVec3fAssign, 1) +HMM_INLINE hmm_vec3 &operator/=(hmm_vec3 &Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec3fAssign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideVec4fAssign, 1) +HMM_INLINE hmm_vec4 &operator/=(hmm_vec4 &Left, float Right) +{ + ASSERT_COVERED(HMM_DivideVec4fAssign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideMat4fAssign, 1) +HMM_INLINE hmm_mat4 &operator/=(hmm_mat4 &Left, float Right) +{ + ASSERT_COVERED(HMM_DivideMat4fAssign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_DivideQuaternionFAssign, 1) +HMM_INLINE hmm_quaternion &operator/=(hmm_quaternion &Left, float Right) +{ + ASSERT_COVERED(HMM_DivideQuaternionFAssign); + + return (Left = Left / Right); +} + +COVERAGE(HMM_EqualsVec2Op, 1) +HMM_INLINE hmm_bool operator==(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_EqualsVec2Op); + + return HMM_PREFIX(EqualsVec2)(Left, Right); +} + +COVERAGE(HMM_EqualsVec3Op, 1) +HMM_INLINE hmm_bool operator==(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_EqualsVec3Op); + + return HMM_PREFIX(EqualsVec3)(Left, Right); +} + +COVERAGE(HMM_EqualsVec4Op, 1) +HMM_INLINE hmm_bool operator==(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_EqualsVec4Op); + + return HMM_PREFIX(EqualsVec4)(Left, Right); +} + +COVERAGE(HMM_EqualsVec2OpNot, 1) +HMM_INLINE hmm_bool operator!=(hmm_vec2 Left, hmm_vec2 Right) +{ + ASSERT_COVERED(HMM_EqualsVec2OpNot); + + return !HMM_PREFIX(EqualsVec2)(Left, Right); +} + +COVERAGE(HMM_EqualsVec3OpNot, 1) +HMM_INLINE hmm_bool operator!=(hmm_vec3 Left, hmm_vec3 Right) +{ + ASSERT_COVERED(HMM_EqualsVec3OpNot); + + return !HMM_PREFIX(EqualsVec3)(Left, Right); +} + +COVERAGE(HMM_EqualsVec4OpNot, 1) +HMM_INLINE hmm_bool operator!=(hmm_vec4 Left, hmm_vec4 Right) +{ + ASSERT_COVERED(HMM_EqualsVec4OpNot); + + return !HMM_PREFIX(EqualsVec4)(Left, Right); +} + +#endif /* __cplusplus */ + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif /* HANDMADE_MATH_H */ + +#ifdef HANDMADE_MATH_IMPLEMENTATION + +COVERAGE(HMM_Power, 2) +float HMM_PREFIX(Power)(float Base, int Exponent) +{ + ASSERT_COVERED(HMM_Power); + + float Result = 1.0f; + float Mul = Exponent < 0 ? 1.f / Base : Base; + int X = Exponent < 0 ? -Exponent : Exponent; + while (X) + { + if (X & 1) + { + ASSERT_COVERED(HMM_Power); + + Result *= Mul; + } + + Mul *= Mul; + X >>= 1; + } + + return (Result); +} + +#ifndef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_Transpose, 1) +hmm_mat4 HMM_PREFIX(Transpose)(hmm_mat4 Matrix) +{ + ASSERT_COVERED(HMM_Transpose); + + hmm_mat4 Result; + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Rows][Columns] = Matrix.Elements[Columns][Rows]; + } + } + + return (Result); +} +#endif + +#ifndef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_AddMat4, 1) +hmm_mat4 HMM_PREFIX(AddMat4)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_AddMat4); + + hmm_mat4 Result; + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] + Right.Elements[Columns][Rows]; + } + } + + return (Result); +} +#endif + +#ifndef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_SubtractMat4, 1) +hmm_mat4 HMM_PREFIX(SubtractMat4)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_SubtractMat4); + + hmm_mat4 Result; + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] - Right.Elements[Columns][Rows]; + } + } + + return (Result); +} +#endif + +COVERAGE(HMM_MultiplyMat4, 1) +hmm_mat4 HMM_PREFIX(MultiplyMat4)(hmm_mat4 Left, hmm_mat4 Right) +{ + ASSERT_COVERED(HMM_MultiplyMat4); + + hmm_mat4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.Columns[0] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[0], Left); + Result.Columns[1] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[1], Left); + Result.Columns[2] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[2], Left); + Result.Columns[3] = HMM_PREFIX(LinearCombineSSE)(Right.Columns[3], Left); +#else + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + float Sum = 0; + int CurrentMatrice; + for(CurrentMatrice = 0; CurrentMatrice < 4; ++CurrentMatrice) + { + Sum += Left.Elements[CurrentMatrice][Rows] * Right.Elements[Columns][CurrentMatrice]; + } + + Result.Elements[Columns][Rows] = Sum; + } + } +#endif + + return (Result); +} + +#ifndef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_MultiplyMat4f, 1) +hmm_mat4 HMM_PREFIX(MultiplyMat4f)(hmm_mat4 Matrix, float Scalar) +{ + ASSERT_COVERED(HMM_MultiplyMat4f); + + hmm_mat4 Result; + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] * Scalar; + } + } + + return (Result); +} +#endif + +COVERAGE(HMM_MultiplyMat4ByVec4, 1) +hmm_vec4 HMM_PREFIX(MultiplyMat4ByVec4)(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + ASSERT_COVERED(HMM_MultiplyMat4ByVec4); + + hmm_vec4 Result; + +#ifdef HANDMADE_MATH__USE_SSE + Result.InternalElementsSSE = HMM_PREFIX(LinearCombineSSE)(Vector.InternalElementsSSE, Matrix); +#else + int Columns, Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + float Sum = 0; + for(Columns = 0; Columns < 4; ++Columns) + { + Sum += Matrix.Elements[Columns][Rows] * Vector.Elements[Columns]; + } + + Result.Elements[Rows] = Sum; + } +#endif + + return (Result); +} + +#ifndef HANDMADE_MATH__USE_SSE +COVERAGE(HMM_DivideMat4f, 1); +hmm_mat4 HMM_PREFIX(DivideMat4f)(hmm_mat4 Matrix, float Scalar) +{ + ASSERT_COVERED(HMM_DivideMat4f); + + hmm_mat4 Result; + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] / Scalar; + } + } + + return (Result); +} +#endif + +COVERAGE(HMM_Rotate, 1) +hmm_mat4 HMM_PREFIX(Rotate)(float Angle, hmm_vec3 Axis) +{ + ASSERT_COVERED(HMM_Rotate); + + hmm_mat4 Result = HMM_PREFIX(Mat4d)(1.0f); + + Axis = HMM_PREFIX(NormalizeVec3)(Axis); + + float SinTheta = HMM_PREFIX(SinF)(HMM_PREFIX(ToRadians)(Angle)); + float CosTheta = HMM_PREFIX(CosF)(HMM_PREFIX(ToRadians)(Angle)); + float CosValue = 1.0f - CosTheta; + + Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta; + Result.Elements[0][1] = (Axis.X * Axis.Y * CosValue) + (Axis.Z * SinTheta); + Result.Elements[0][2] = (Axis.X * Axis.Z * CosValue) - (Axis.Y * SinTheta); + + Result.Elements[1][0] = (Axis.Y * Axis.X * CosValue) - (Axis.Z * SinTheta); + Result.Elements[1][1] = (Axis.Y * Axis.Y * CosValue) + CosTheta; + Result.Elements[1][2] = (Axis.Y * Axis.Z * CosValue) + (Axis.X * SinTheta); + + Result.Elements[2][0] = (Axis.Z * Axis.X * CosValue) + (Axis.Y * SinTheta); + Result.Elements[2][1] = (Axis.Z * Axis.Y * CosValue) - (Axis.X * SinTheta); + Result.Elements[2][2] = (Axis.Z * Axis.Z * CosValue) + CosTheta; + + return (Result); +} + +COVERAGE(HMM_LookAt, 1) +hmm_mat4 HMM_PREFIX(LookAt)(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up) +{ + ASSERT_COVERED(HMM_LookAt); + + hmm_mat4 Result; + + hmm_vec3 F = HMM_PREFIX(NormalizeVec3)(HMM_PREFIX(SubtractVec3)(Center, Eye)); + hmm_vec3 S = HMM_PREFIX(NormalizeVec3)(HMM_PREFIX(Cross)(F, Up)); + hmm_vec3 U = HMM_PREFIX(Cross)(S, F); + + Result.Elements[0][0] = S.X; + Result.Elements[0][1] = U.X; + Result.Elements[0][2] = -F.X; + Result.Elements[0][3] = 0.0f; + + Result.Elements[1][0] = S.Y; + Result.Elements[1][1] = U.Y; + Result.Elements[1][2] = -F.Y; + Result.Elements[1][3] = 0.0f; + + Result.Elements[2][0] = S.Z; + Result.Elements[2][1] = U.Z; + Result.Elements[2][2] = -F.Z; + Result.Elements[2][3] = 0.0f; + + Result.Elements[3][0] = -HMM_PREFIX(DotVec3)(S, Eye); + Result.Elements[3][1] = -HMM_PREFIX(DotVec3)(U, Eye); + Result.Elements[3][2] = HMM_PREFIX(DotVec3)(F, Eye); + Result.Elements[3][3] = 1.0f; + + return (Result); +} + +COVERAGE(HMM_InverseQuaternion, 1) +hmm_quaternion HMM_PREFIX(InverseQuaternion)(hmm_quaternion Left) +{ + ASSERT_COVERED(HMM_InverseQuaternion); + + hmm_quaternion Conjugate; + hmm_quaternion Result; + float Norm = 0; + float NormSquared = 0; + + Conjugate.X = -Left.X; + Conjugate.Y = -Left.Y; + Conjugate.Z = -Left.Z; + Conjugate.W = Left.W; + + Norm = HMM_PREFIX(SquareRootF)(HMM_PREFIX(DotQuaternion)(Left, Left)); + NormSquared = Norm * Norm; + + Result = HMM_PREFIX(DivideQuaternionF)(Conjugate, NormSquared); + + return (Result); +} + +COVERAGE(HMM_Slerp, 1) +hmm_quaternion HMM_PREFIX(Slerp)(hmm_quaternion Left, float Time, hmm_quaternion Right) +{ + ASSERT_COVERED(HMM_Slerp); + + hmm_quaternion Result; + hmm_quaternion QuaternionLeft; + hmm_quaternion QuaternionRight; + + float Cos_Theta = HMM_PREFIX(DotQuaternion)(Left, Right); + float Angle = HMM_PREFIX(ACosF)(Cos_Theta); + + float S1 = HMM_PREFIX(SinF)((1.0f - Time) * Angle); + float S2 = HMM_PREFIX(SinF)(Time * Angle); + float Is = 1.0f / HMM_PREFIX(SinF)(Angle); + + QuaternionLeft = HMM_PREFIX(MultiplyQuaternionF)(Left, S1); + QuaternionRight = HMM_PREFIX(MultiplyQuaternionF)(Right, S2); + + Result = HMM_PREFIX(AddQuaternion)(QuaternionLeft, QuaternionRight); + Result = HMM_PREFIX(MultiplyQuaternionF)(Result, Is); + + return (Result); +} + +COVERAGE(HMM_QuaternionToMat4, 1) +hmm_mat4 HMM_PREFIX(QuaternionToMat4)(hmm_quaternion Left) +{ + ASSERT_COVERED(HMM_QuaternionToMat4); + + hmm_mat4 Result; + + hmm_quaternion NormalizedQuaternion = HMM_PREFIX(NormalizeQuaternion)(Left); + + float XX, YY, ZZ, + XY, XZ, YZ, + WX, WY, WZ; + + XX = NormalizedQuaternion.X * NormalizedQuaternion.X; + YY = NormalizedQuaternion.Y * NormalizedQuaternion.Y; + ZZ = NormalizedQuaternion.Z * NormalizedQuaternion.Z; + XY = NormalizedQuaternion.X * NormalizedQuaternion.Y; + XZ = NormalizedQuaternion.X * NormalizedQuaternion.Z; + YZ = NormalizedQuaternion.Y * NormalizedQuaternion.Z; + WX = NormalizedQuaternion.W * NormalizedQuaternion.X; + WY = NormalizedQuaternion.W * NormalizedQuaternion.Y; + WZ = NormalizedQuaternion.W * NormalizedQuaternion.Z; + + Result.Elements[0][0] = 1.0f - 2.0f * (YY + ZZ); + Result.Elements[0][1] = 2.0f * (XY + WZ); + Result.Elements[0][2] = 2.0f * (XZ - WY); + Result.Elements[0][3] = 0.0f; + + Result.Elements[1][0] = 2.0f * (XY - WZ); + Result.Elements[1][1] = 1.0f - 2.0f * (XX + ZZ); + Result.Elements[1][2] = 2.0f * (YZ + WX); + Result.Elements[1][3] = 0.0f; + + Result.Elements[2][0] = 2.0f * (XZ + WY); + Result.Elements[2][1] = 2.0f * (YZ - WX); + Result.Elements[2][2] = 1.0f - 2.0f * (XX + YY); + Result.Elements[2][3] = 0.0f; + + Result.Elements[3][0] = 0.0f; + Result.Elements[3][1] = 0.0f; + Result.Elements[3][2] = 0.0f; + Result.Elements[3][3] = 1.0f; + + return (Result); +} + +// This method taken from Mike Day at Insomniac Games. +// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf +// +// Note that as mentioned at the top of the paper, the paper assumes the matrix +// would be *post*-multiplied to a vector to rotate it, meaning the matrix is +// the transpose of what we're dealing with. But, because our matrices are +// stored in column-major order, the indices *appear* to match the paper. +// +// For example, m12 in the paper is row 1, column 2. We need to transpose it to +// row 2, column 1. But, because the column comes first when referencing +// elements, it looks like M.Elements[1][2]. +// +// Don't be confused! Or if you must be confused, at least trust this +// comment. :) +COVERAGE(HMM_Mat4ToQuaternion, 4) +hmm_quaternion HMM_PREFIX(Mat4ToQuaternion)(hmm_mat4 M) +{ + float T; + hmm_quaternion Q; + + if (M.Elements[2][2] < 0.0f) { + if (M.Elements[0][0] > M.Elements[1][1]) { + ASSERT_COVERED(HMM_Mat4ToQuaternion); + + T = 1 + M.Elements[0][0] - M.Elements[1][1] - M.Elements[2][2]; + Q = HMM_PREFIX(Quaternion)( + T, + M.Elements[0][1] + M.Elements[1][0], + M.Elements[2][0] + M.Elements[0][2], + M.Elements[1][2] - M.Elements[2][1] + ); + } else { + ASSERT_COVERED(HMM_Mat4ToQuaternion); + + T = 1 - M.Elements[0][0] + M.Elements[1][1] - M.Elements[2][2]; + Q = HMM_PREFIX(Quaternion)( + M.Elements[0][1] + M.Elements[1][0], + T, + M.Elements[1][2] + M.Elements[2][1], + M.Elements[2][0] - M.Elements[0][2] + ); + } + } else { + if (M.Elements[0][0] < -M.Elements[1][1]) { + ASSERT_COVERED(HMM_Mat4ToQuaternion); + + T = 1 - M.Elements[0][0] - M.Elements[1][1] + M.Elements[2][2]; + Q = HMM_PREFIX(Quaternion)( + M.Elements[2][0] + M.Elements[0][2], + M.Elements[1][2] + M.Elements[2][1], + T, + M.Elements[0][1] - M.Elements[1][0] + ); + } else { + ASSERT_COVERED(HMM_Mat4ToQuaternion); + + T = 1 + M.Elements[0][0] + M.Elements[1][1] + M.Elements[2][2]; + Q = HMM_PREFIX(Quaternion)( + M.Elements[1][2] - M.Elements[2][1], + M.Elements[2][0] - M.Elements[0][2], + M.Elements[0][1] - M.Elements[1][0], + T + ); + } + } + + Q = HMM_PREFIX(MultiplyQuaternionF)(Q, 0.5f / HMM_PREFIX(SquareRootF)(T)); + + return Q; +} + +COVERAGE(HMM_QuaternionFromAxisAngle, 1) +hmm_quaternion HMM_PREFIX(QuaternionFromAxisAngle)(hmm_vec3 Axis, float AngleOfRotation) +{ + ASSERT_COVERED(HMM_QuaternionFromAxisAngle); + + hmm_quaternion Result; + + hmm_vec3 AxisNormalized = HMM_PREFIX(NormalizeVec3)(Axis); + float SineOfRotation = HMM_PREFIX(SinF)(AngleOfRotation / 2.0f); + + Result.XYZ = HMM_PREFIX(MultiplyVec3f)(AxisNormalized, SineOfRotation); + Result.W = HMM_PREFIX(CosF)(AngleOfRotation / 2.0f); + + return (Result); +} + +#endif /* HANDMADE_MATH_IMPLEMENTATION */ diff --git a/examples/sokol/rt_glsl/default_include.h b/examples/sokol/rt_glsl/default_include.h new file mode 100644 index 0000000000..da79e01100 --- /dev/null +++ b/examples/sokol/rt_glsl/default_include.h @@ -0,0 +1,27 @@ +#define HANDMADE_MATH_IMPLEMENTATION +#define HANDMADE_MATH_NO_SSE +#include "HandmadeMath.h" + +void calc_matrices(void *res, float w, float h, float rx, float ry, float scale){ + hmm_mat4 proj = HMM_Perspective(60.0f, w/h, 0.01f, 10.0f); + hmm_mat4 view = HMM_LookAt(HMM_Vec3(0.0f, 0.0f, 6.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f)); + hmm_mat4 view_proj = HMM_MultiplyMat4(proj, view); + //state.rx += 1.0f; state.ry += 2.0f; + + + hmm_mat4 rxm = HMM_Rotate(rx, HMM_Vec3(1.0f, 0.0f, 0.0f)); + hmm_mat4 rym = HMM_Rotate(ry, HMM_Vec3(0.0f, 1.0f, 0.0f)); + + hmm_mat4 model = HMM_MultiplyMat4(rxm, rym); + hmm_mat4 scale_mx = HMM_Scale(HMM_Vec3(scale, scale, scale)); + model = HMM_MultiplyMat4(model, scale_mx); + hmm_mat4 tmp_res = HMM_MultiplyMat4(view_proj, model); + + // copy the matrix to V + int i = 0; + float *p = &tmp_res.Elements[0]; + while(i < 16){ + ((float*)(res))[i]= p[i]; + i++; + } +} \ No newline at end of file diff --git a/examples/sokol/rt_glsl/rt_glsl.glsl b/examples/sokol/rt_glsl/rt_glsl.glsl new file mode 100644 index 0000000000..0d31ef7fd2 --- /dev/null +++ b/examples/sokol/rt_glsl/rt_glsl.glsl @@ -0,0 +1,695 @@ +//------------------------------------------------------------------------------ +// Shader code for texcube-sapp sample. +// +// NOTE: This source file also uses the '#pragma sokol' form of the +// custom tags. +//------------------------------------------------------------------------------ +#pragma sokol @ctype mat4 hmm_mat4 + +#pragma sokol @vs vs +uniform vs_params { + mat4 mvp; +}; + +in vec4 pos; +in vec4 color0; +in vec2 texcoord0; + +out vec4 color; +out vec2 uv; + +void main() { + gl_Position = mvp * pos; + color = color0; + uv = texcoord0; +} +#pragma sokol @end + +#pragma sokol @fs fs +uniform sampler2D tex; +uniform fs_params { + vec2 iResolution; + vec2 iMouse; + float iTime; + float iFrame; +}; + +in vec4 color; +in vec2 uv; +out vec4 frag_color; + +// change to 0 to 4 to increment the AntiAliasing, +// increase AA will SLOW the rendering!! +#define AA 1 + +//********************************************************* +// Ray Marching +// original code from: https://www.shadertoy.com/view/Xds3zN +//********************************************************* +// The MIT License +// Copyright © 2013 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A list of useful distance function to simple primitives. All +// these functions (except for ellipsoid) return an exact +// euclidean distance, meaning they produce a better SDF than +// what you'd get if you were constructing them from boolean +// operations. +// +// More info here: +// +// https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + +//------------------------------------------------------------------ +float dot2( in vec2 v ) { return dot(v,v); } +float dot2( in vec3 v ) { return dot(v,v); } +float ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; } + +float sdPlane( vec3 p ) +{ + return p.y; +} + +float sdSphere( vec3 p, float s ) +{ + return length(p)-s; +} + +float sdBox( vec3 p, vec3 b ) +{ + vec3 d = abs(p) - b; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + +float sdBoundingBox( vec3 p, vec3 b, float e ) +{ + p = abs(p )-b; + vec3 q = abs(p+e)-e; + + return min(min( + length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0), + length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)), + length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0)); +} +float sdEllipsoid( in vec3 p, in vec3 r ) // approximated +{ + float k0 = length(p/r); + float k1 = length(p/(r*r)); + return k0*(k0-1.0)/k1; +} + +float sdTorus( vec3 p, vec2 t ) +{ + return length( vec2(length(p.xz)-t.x,p.y) )-t.y; +} + +float sdCappedTorus(in vec3 p, in vec2 sc, in float ra, in float rb) +{ + p.x = abs(p.x); + float k = (sc.y*p.x>sc.x*p.y) ? dot(p.xy,sc) : length(p.xy); + return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb; +} + +float sdHexPrism( vec3 p, vec2 h ) +{ + vec3 q = abs(p); + + const vec3 k = vec3(-0.8660254, 0.5, 0.57735); + p = abs(p); + p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy; + vec2 d = vec2( + length(p.xy - vec2(clamp(p.x, -k.z*h.x, k.z*h.x), h.x))*sign(p.y - h.x), + p.z-h.y ); + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +float sdOctogonPrism( in vec3 p, in float r, float h ) +{ + const vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 + 0.3826834323, // sqrt(2-sqrt(2))/2 + 0.4142135623 ); // sqrt(2)-1 + // reflections + p = abs(p); + p.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y); + p.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y); + // polygon side + p.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r); + vec2 d = vec2( length(p.xy)*sign(p.y), p.z-h ); + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) +{ + vec3 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ) - r; +} + +float sdRoundCone( in vec3 p, in float r1, float r2, float h ) +{ + vec2 q = vec2( length(p.xz), p.y ); + + float b = (r1-r2)/h; + float a = sqrt(1.0-b*b); + float k = dot(q,vec2(-b,a)); + + if( k < 0.0 ) return length(q) - r1; + if( k > a*h ) return length(q-vec2(0.0,h)) - r2; + + return dot(q, vec2(a,b) ) - r1; +} + +float sdRoundCone(vec3 p, vec3 a, vec3 b, float r1, float r2) +{ + // sampling independent computations (only depend on shape) + vec3 ba = b - a; + float l2 = dot(ba,ba); + float rr = r1 - r2; + float a2 = l2 - rr*rr; + float il2 = 1.0/l2; + + // sampling dependant computations + vec3 pa = p - a; + float y = dot(pa,ba); + float z = y - l2; + float x2 = dot2( pa*l2 - ba*y ); + float y2 = y*y*l2; + float z2 = z*z*l2; + + // single square root! + float k = sign(rr)*rr*rr*x2; + if( sign(z)*a2*z2 > k ) return sqrt(x2 + z2) *il2 - r2; + if( sign(y)*a2*y2 < k ) return sqrt(x2 + y2) *il2 - r1; + return (sqrt(x2*a2*il2)+y*rr)*il2 - r1; +} + +float sdTriPrism( vec3 p, vec2 h ) +{ + const float k = sqrt(3.0); + h.x *= 0.5*k; + p.xy /= h.x; + p.x = abs(p.x) - 1.0; + p.y = p.y + 1.0/k; + if( p.x+k*p.y>0.0 ) p.xy=vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; + p.x -= clamp( p.x, -2.0, 0.0 ); + float d1 = length(p.xy)*sign(-p.y)*h.x; + float d2 = abs(p.z)-h.y; + return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.); +} + +// vertical +float sdCylinder( vec3 p, vec2 h ) +{ + vec2 d = abs(vec2(length(p.xz),p.y)) - h; + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +// arbitrary orientation +float sdCylinder(vec3 p, vec3 a, vec3 b, float r) +{ + vec3 pa = p - a; + vec3 ba = b - a; + float baba = dot(ba,ba); + float paba = dot(pa,ba); + + float x = length(pa*baba-ba*paba) - r*baba; + float y = abs(paba-baba*0.5)-baba*0.5; + float x2 = x*x; + float y2 = y*y*baba; + float d = (max(x,y)<0.0)?-min(x2,y2):(((x>0.0)?x2:0.0)+((y>0.0)?y2:0.0)); + return sign(d)*sqrt(abs(d))/baba; +} + +// vertical +float sdCone( in vec3 p, in vec2 c, float h ) +{ + vec2 q = h*vec2(c.x,-c.y)/c.y; + vec2 w = vec2( length(p.xz), p.y ); + + vec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 ); + vec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 ); + float k = sign( q.y ); + float d = min(dot( a, a ),dot(b, b)); + float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) ); + return sqrt(d)*sign(s); +} + +float sdCappedCone( in vec3 p, in float h, in float r1, in float r2 ) +{ + vec2 q = vec2( length(p.xz), p.y ); + + vec2 k1 = vec2(r2,h); + vec2 k2 = vec2(r2-r1,2.0*h); + vec2 ca = vec2(q.x-min(q.x,(q.y < 0.0)?r1:r2), abs(q.y)-h); + vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot2(k2), 0.0, 1.0 ); + float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0; + return s*sqrt( min(dot2(ca),dot2(cb)) ); +} + +float sdCappedCone(vec3 p, vec3 a, vec3 b, float ra, float rb) +{ + float rba = rb-ra; + float baba = dot(b-a,b-a); + float papa = dot(p-a,p-a); + float paba = dot(p-a,b-a)/baba; + + float x = sqrt( papa - paba*paba*baba ); + + float cax = max(0.0,x-((paba<0.5)?ra:rb)); + float cay = abs(paba-0.5)-0.5; + + float k = rba*rba + baba; + float f = clamp( (rba*(x-ra)+paba*baba)/k, 0.0, 1.0 ); + + float cbx = x-ra - f*rba; + float cby = paba - f; + + float s = (cbx < 0.0 && cay < 0.0) ? -1.0 : 1.0; + + return s*sqrt( min(cax*cax + cay*cay*baba, + cbx*cbx + cby*cby*baba) ); +} + +// c is the sin/cos of the desired cone angle +float sdSolidAngle(vec3 pos, vec2 c, float ra) +{ + vec2 p = vec2( length(pos.xz), pos.y ); + float l = length(p) - ra; + float m = length(p - c*clamp(dot(p,c),0.0,ra) ); + return max(l,m*sign(c.y*p.x-c.x*p.y)); +} + +float sdOctahedron(vec3 p, float s) +{ + p = abs(p); + float m = p.x + p.y + p.z - s; + +// exact distance +#if 0 + vec3 o = min(3.0*p - m, 0.0); + o = max(6.0*p - m*2.0 - o*3.0 + (o.x+o.y+o.z), 0.0); + return length(p - s*o/(o.x+o.y+o.z)); +#endif + +// exact distance +#if 1 + vec3 q; + if( 3.0*p.x < m ) q = p.xyz; + else if( 3.0*p.y < m ) q = p.yzx; + else if( 3.0*p.z < m ) q = p.zxy; + else return m*0.57735027; + float k = clamp(0.5*(q.z-q.y+s),0.0,s); + return length(vec3(q.x,q.y-s+k,q.z-k)); +#endif + +// bound, not exact +#if 0 + return m*0.57735027; +#endif +} + +float sdPyramid( in vec3 p, in float h ) +{ + float m2 = h*h + 0.25; + + // symmetry + p.xz = abs(p.xz); + p.xz = (p.z>p.x) ? p.zx : p.xz; + p.xz -= 0.5; + + // project into face plane (2D) + vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); + + float s = max(-q.x,0.0); + float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); + + float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; + float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); + + float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); + + // recover 3D and scale, and add sign + return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y)); +} + +// la,lb=semi axis, h=height, ra=corner +float sdRhombus(vec3 p, float la, float lb, float h, float ra) +{ + p = abs(p); + vec2 b = vec2(la,lb); + float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); + vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); + return min(max(q.x,q.y),0.0) + length(max(q,0.0)); +} + +//------------------------------------------------------------------ + +vec2 opU( vec2 d1, vec2 d2 ) +{ + return (d1.x0.0 ) + { + tmax = min( tmax, tp1 ); + res = vec2( tp1, 1.0 ); + } + //else return res; + + // raymarch primitives + vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); + if( tb.x0.0 && tb.x0.0 ) tmax = min( tmax, tp ); + + float res = 1.0; + float t = mint; + for( int i=ZERO; i<24; i++ ) + { + float h = map( ro + rd*t ).x; + float s = clamp(8.0*h/t,0.0,1.0); + res = min( res, s*s*(3.0-2.0*s) ); + t += clamp( h, 0.02, 0.2 ); + if( res<0.004 || t>tmax ) break; + } + return clamp( res, 0.0, 1.0 ); +} + +// http://iquilezles.org/www/articles/normalsSDF/normalsSDF.htm +vec3 calcNormal( in vec3 pos ) +{ +#if 0 + vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; + return normalize( e.xyy*map( pos + e.xyy ).x + + e.yyx*map( pos + e.yyx ).x + + e.yxy*map( pos + e.yxy ).x + + e.xxx*map( pos + e.xxx ).x ); +#else + // inspired by tdhooper and klems - a way to prevent the compiler from inlining map() 4 times + vec3 n = vec3(0.0); + for( int i=ZERO; i<4; i++ ) + { + vec3 e = 0.5773*(2.0*vec3((((i+3)>>1)&1),((i>>1)&1),(i&1))-1.0); + n += e*map(pos+0.0005*e).x; + //if( n.x+n.y+n.z>100.0 ) break; + } + return normalize(n); +#endif +} + +float calcAO( in vec3 pos, in vec3 nor ) +{ + float occ = 0.0; + float sca = 1.0; + for( int i=ZERO; i<5; i++ ) + { + float h = 0.01 + 0.12*float(i)/4.0; + float d = map( pos + h*nor ).x; + occ += (h-d)*sca; + sca *= 0.95; + if( occ>0.35 ) break; + } + return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y); +} + +// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm +float checkersGradBox( in vec2 p, in vec2 dpdx, in vec2 dpdy ) +{ + // filter kernel + vec2 w = abs(dpdx)+abs(dpdy) + 0.001; + // analytical integral (box filter) + vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; + // xor pattern + return 0.5 - 0.5*i.x*i.y; +} + +vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) +{ + // background + vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; + + // raycast scene + vec2 res = raycast(ro,rd); + float t = res.x; + float m = res.y; + if( m>-0.5 ) + { + vec3 pos = ro + t*rd; + vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); + vec3 ref = reflect( rd, nor ); + + // material + col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); + float ks = 1.0; + + if( m<1.5 ) + { + // project pixel footprint into the plane + vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); + vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); + + float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); + col = 0.15 + f*vec3(0.05); + ks = 0.4; + } + + // lighting + float occ = calcAO( pos, nor ); + + vec3 lin = vec3(0.0); + + // sun + { + vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); + vec3 hal = normalize( lig-rd ); + float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); + //if( dif>0.0001 ) + dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); + float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); + spe *= dif; + spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); + lin += col*2.20*dif*vec3(1.30,1.00,0.70); + lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; + } + // sky + { + float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); + dif *= occ; + float spe = smoothstep( -0.2, 0.2, ref.y ); + spe *= dif; + spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); + //if( spe>0.001 ) + spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); + lin += col*0.60*dif*vec3(0.40,0.60,1.15); + lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; + } + // back + { + float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); + dif *= occ; + lin += col*0.55*dif*vec3(0.25,0.25,0.25); + } + // sss + { + float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); + dif *= occ; + lin += col*0.25*dif*vec3(1.00,1.00,1.00); + } + + col = lin; + + col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); + } + + return vec3( clamp(col,0.0,1.0) ); +} + +mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) +{ + vec3 cw = normalize(ta-ro); + vec3 cp = vec3(sin(cr), cos(cr),0.0); + vec3 cu = normalize( cross(cw,cp) ); + vec3 cv = ( cross(cu,cw) ); + return mat3( cu, cv, cw ); +} + +vec4 mainImage( vec2 fragCoord ) +{ + vec2 mo = iMouse.xy/iResolution.xy; + float time = 32.0 + iTime*1.5; + + // camera + vec3 ta = vec3( 0.5, -0.5, -0.6 ); + vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 1.3 + 2.0*mo.y, 4.5*sin(0.1*time + 7.0*mo.x) ); + // camera-to-world transformation + mat3 ca = setCamera( ro, ta, 0.0 ); + + vec3 tot = vec3(0.0); +#if AA>1 + for( int m=ZERO; m1 + } + tot /= float(AA*AA); +#endif + + //fragColor = vec4( tot, 1.0 ); + return vec4( tot, 1.0 ); +} + +//********************************************************* +// END Ray Marching +//********************************************************* + +void main() { + vec4 c = color; + vec4 txt = texture(tex, uv); + c = txt * c; + vec2 uv1 = uv * iResolution; + vec4 col_ray = mainImage(uv1); + + // use this to mix the chessboart texture with the ray marching + //frag_color = clamp(c*iMouse.y/512.0,0.0,1.0) * col_ray ; + + frag_color = c*0.00001 + col_ray ; +} + +#pragma sokol @end + +#pragma sokol @program rt vs fs diff --git a/examples/sokol/rt_glsl/rt_glsl.h b/examples/sokol/rt_glsl/rt_glsl.h new file mode 100644 index 0000000000..a4b3b2ffaf --- /dev/null +++ b/examples/sokol/rt_glsl/rt_glsl.h @@ -0,0 +1,2686 @@ +#pragma once +/* + #version:1# (machine generated, don't edit!) + + Generated by sokol-shdc (https://github.com/floooh/sokol-tools) + + Overview: + + Shader program 'rt': + Get shader desc: rt_shader_desc() + Vertex shader: vs + Attribute slots: + ATTR_vs_pos = 0 + ATTR_vs_color0 = 1 + ATTR_vs_texcoord0 = 2 + Uniform block 'vs_params': + C struct: vs_params_t + Bind slot: SLOT_vs_params = 0 + Fragment shader: fs + Uniform block 'fs_params': + C struct: fs_params_t + Bind slot: SLOT_fs_params = 0 + Image 'tex': + Type: SG_IMAGETYPE_2D + Component Type: SG_SAMPLERTYPE_FLOAT + Bind slot: SLOT_tex = 0 + + + Shader descriptor structs: + + sg_shader rt = sg_make_shader(rt_shader_desc()); + + Vertex attribute locations for vertex shader 'vs': + + sg_pipeline pip = sg_make_pipeline(&(sg_pipeline_desc){ + .layout = { + .attrs = { + [ATTR_vs_pos] = { ... }, + [ATTR_vs_color0] = { ... }, + [ATTR_vs_texcoord0] = { ... }, + }, + }, + ...}); + + Image bind slots, use as index in sg_bindings.vs_images[] or .fs_images[] + + SLOT_tex = 0; + + Bind slot and C-struct for uniform block 'vs_params': + + vs_params_t vs_params = { + .mvp = ...; + }; + sg_apply_uniforms(SG_SHADERSTAGE_[VS|FS], SLOT_vs_params, &vs_params, sizeof(vs_params)); + + Bind slot and C-struct for uniform block 'fs_params': + + fs_params_t fs_params = { + .iResolution = ...; + .iMouse = ...; + .iTime = ...; + .iFrame = ...; + }; + sg_apply_uniforms(SG_SHADERSTAGE_[VS|FS], SLOT_fs_params, &fs_params, sizeof(fs_params)); + +*/ +#include +#include +#if !defined(SOKOL_SHDC_ALIGN) + #if defined(_MSC_VER) + #define SOKOL_SHDC_ALIGN(a) __declspec(align(a)) + #else + #define SOKOL_SHDC_ALIGN(a) __attribute__((aligned(a))) + #endif +#endif +#define ATTR_vs_pos (0) +#define ATTR_vs_color0 (1) +#define ATTR_vs_texcoord0 (2) +#define SLOT_tex (0) +#define SLOT_vs_params (0) +#pragma pack(push,1) +SOKOL_SHDC_ALIGN(16) typedef struct vs_params_t { + hmm_mat4 mvp; +} vs_params_t; +#pragma pack(pop) +#define SLOT_fs_params (0) +#pragma pack(push,1) +SOKOL_SHDC_ALIGN(16) typedef struct fs_params_t { + float iResolution[2]; + float iMouse[2]; + float iTime; + float iFrame; + uint8_t _pad_24[8]; +} fs_params_t; +#pragma pack(pop) +/* + #version 330 + + uniform vec4 vs_params[4]; + layout(location = 0) in vec4 pos; + out vec4 color; + layout(location = 1) in vec4 color0; + out vec2 uv; + layout(location = 2) in vec2 texcoord0; + + void main() + { + gl_Position = mat4(vs_params[0], vs_params[1], vs_params[2], vs_params[3]) * pos; + color = color0; + uv = texcoord0; + } + +*/ +static const char vs_source_glsl330[326] = { + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e, + 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61, + 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28, + 0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e, + 0x20,0x76,0x65,0x63,0x34,0x20,0x70,0x6f,0x73,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76, + 0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75, + 0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20, + 0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a, + 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79, + 0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x32, + 0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f, + 0x72,0x64,0x30,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28, + 0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74, + 0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x76,0x73,0x5f,0x70,0x61, + 0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61, + 0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73, + 0x5b,0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33, + 0x5d,0x29,0x20,0x2a,0x20,0x70,0x6f,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f, + 0x6c,0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30, + 0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +}; +/* + #version 330 + + uniform vec4 fs_params[2]; + uniform sampler2D tex; + + in vec4 color; + in vec2 uv; + layout(location = 0) out vec4 frag_color; + + mat3 setCamera(vec3 ro, vec3 ta, float cr) + { + vec3 _2646 = normalize(ta - ro); + vec3 _2657 = normalize(cross(_2646, vec3(sin(cr), cos(cr), 0.0))); + return mat3(_2657, cross(_2657, _2646), _2646); + } + + vec2 iBox(vec3 ro, vec3 rd, vec3 rad) + { + vec3 _1959 = vec3(1.0) / rd; + vec3 _1968 = abs(_1959) * rad; + vec3 _1971 = -(_1959 * ro); + vec3 _1973 = _1971 - _1968; + vec3 _1978 = _1971 + _1968; + return vec2(max(max(_1973.x, _1973.y), _1973.z), min(min(_1978.x, _1978.y), _1978.z)); + } + + float sdSphere(vec3 p, float s) + { + return length(p) - s; + } + + vec2 opU(vec2 d1, vec2 d2) + { + bvec2 _1585 = bvec2(d1.x < d2.x); + return vec2(_1585.x ? d1.x : d2.x, _1585.y ? d1.y : d2.y); + } + + float sdBox(vec3 p, vec3 b) + { + vec3 _240 = abs(p) - b; + return min(max(_240.x, max(_240.y, _240.z)), 0.0) + length(max(_240, vec3(0.0))); + } + + float sdBoundingBox(inout vec3 p, vec3 b, float e) + { + p = abs(p) - b; + vec3 _271 = abs(p + vec3(e)) - vec3(e); + float _275 = _271.y; + float _277 = _271.z; + float _293 = _271.x; + return min(min(length(max(vec3(p.x, _275, _277), vec3(0.0))) + min(max(p.x, max(_275, _277)), 0.0), length(max(vec3(_293, p.y, _277), vec3(0.0))) + min(max(_293, max(p.y, _277)), 0.0)), length(max(vec3(_293, _275, p.z), vec3(0.0))) + min(max(_293, max(_275, p.z)), 0.0)); + } + + float sdTorus(vec3 p, vec2 t) + { + return length(vec2(length(p.xz) - t.x, p.y)) - t.y; + } + + float sdCone(vec3 p, vec2 c, float h) + { + vec2 _965 = (vec2(c.x, -c.y) * h) / vec2(c.y); + float _969 = length(p.xz); + vec2 _972 = vec2(_969, p.y); + vec2 _985 = _972 - (_965 * clamp(dot(_972, _965) / dot(_965, _965), 0.0, 1.0)); + float _992 = _965.x; + vec2 _997 = _972 - (_965 * vec2(clamp(_969 / _992, 0.0, 1.0), 1.0)); + float _1000 = _965.y; + float _1001 = sign(_1000); + return sqrt(min(dot(_985, _985), dot(_997, _997))) * sign(max(_1001 * ((_969 * _1000) - (p.y * _992)), _1001 * (p.y - _1000))); + } + + float dot2(vec2 v) + { + return dot(v, v); + } + + float sdCappedCone(vec3 p, float h, float r1, float r2) + { + float _1042 = length(p.xz); + vec2 _1045 = vec2(_1042, p.y); + vec2 _1049 = vec2(r2, h); + vec2 _1056 = vec2(r2 - r1, 2.0 * h); + float _1074 = abs(p.y) - h; + vec2 param = _1056; + vec2 _1092 = (_1045 - _1049) + (_1056 * clamp(dot(_1049 - _1045, _1056) / dot2(param), 0.0, 1.0)); + bool _1096 = _1092.x < 0.0; + bool _1102; + if (_1096) + { + _1102 = _1074 < 0.0; + } + else + { + _1102 = _1096; + } + vec2 param_1 = vec2(_1042 - min(_1042, (p.y < 0.0) ? r1 : r2), _1074); + vec2 param_2 = _1092; + return (_1102 ? (-1.0) : 1.0) * sqrt(min(dot2(param_1), dot2(param_2))); + } + + float sdSolidAngle(vec3 pos, vec2 c, float ra) + { + float _1235 = length(pos.xz); + vec2 _1238 = vec2(_1235, pos.y); + return max(length(_1238) - ra, length(_1238 - (c * clamp(dot(_1238, c), 0.0, ra))) * sign((c.y * _1235) - (c.x * pos.y))); + } + + float sdCappedTorus(inout vec3 p, vec2 sc, float ra, float rb) + { + p.x = abs(p.x); + float _389; + if ((sc.y * p.x) > (sc.x * p.y)) + { + _389 = dot(p.xy, sc); + } + else + { + _389 = length(p.xy); + } + return sqrt((dot(p, p) + (ra * ra)) - ((2.0 * ra) * _389)) - rb; + } + + float sdCapsule(vec3 p, vec3 a, vec3 b, float r) + { + vec3 _557 = p - a; + vec3 _561 = b - a; + return length(_557 - (_561 * clamp(dot(_557, _561) / dot(_561, _561), 0.0, 1.0))) - r; + } + + float sdCylinder(vec3 p, vec2 h) + { + vec2 _858 = abs(vec2(length(p.xz), p.y)) - h; + return min(max(_858.x, _858.y), 0.0) + length(max(_858, vec2(0.0))); + } + + float sdHexPrism(inout vec3 p, vec2 h) + { + p = abs(p); + vec2 _435 = p.xy - (vec2(-0.866025388240814208984375, 0.5) * (2.0 * min(dot(vec2(-0.866025388240814208984375, 0.5), p.xy), 0.0))); + p = vec3(_435.x, _435.y, p.z); + float _463 = length(p.xy - vec2(clamp(p.x, (-0.57735002040863037109375) * h.x, 0.57735002040863037109375 * h.x), h.x)) * sign(p.y - h.x); + float _468 = p.z - h.y; + return min(max(_463, _468), 0.0) + length(max(vec2(_463, _468), vec2(0.0))); + } + + float sdPyramid(inout vec3 p, float h) + { + float _1350 = h * h; + float _1352 = _1350 + 0.25; + vec2 _1355 = abs(p.xz); + p = vec3(_1355.x, p.y, _1355.y); + vec2 _1363; + if (p.z > p.x) + { + _1363 = p.zx; + } + else + { + _1363 = p.xz; + } + p = vec3(_1363.x, p.y, _1363.y); + vec2 _1377 = p.xz - vec2(0.5); + p = vec3(_1377.x, p.y, _1377.y); + float _1390 = (h * p.y) - (0.5 * p.x); + float _1398 = (h * p.x) + (0.5 * p.y); + float _1403 = -p.z; + float _1415 = clamp((_1390 - (0.5 * p.z)) / (_1350 + 0.5), 0.0, 1.0); + float _1421 = p.z + max(_1403, 0.0); + float _1440 = p.z + (0.5 * _1415); + float _1453 = _1390 - (_1352 * _1415); + float _1476; + if (min(_1390, (_1403 * _1352) - (_1390 * 0.5)) > 0.0) + { + _1476 = 0.0; + } + else + { + _1476 = min(((_1352 * _1421) * _1421) + (_1390 * _1390), ((_1352 * _1440) * _1440) + (_1453 * _1453)); + } + return sqrt((_1476 + (_1398 * _1398)) / _1352) * sign(max(_1398, -p.y)); + } + + float sdOctahedron(inout vec3 p, float s) + { + p = abs(p); + float _1285 = ((p.x + p.y) + p.z) - s; + vec3 q; + if ((3.0 * p.x) < _1285) + { + q = p; + } + else + { + if ((3.0 * p.y) < _1285) + { + q = p.yzx; + } + else + { + if ((3.0 * p.z) < _1285) + { + q = p.zxy; + } + else + { + return _1285 * 0.57735025882720947265625; + } + } + } + float _1330 = clamp(0.5 * ((q.z - q.y) + s), 0.0, s); + return length(vec3(q.x, (q.y - s) + _1330, q.z - _1330)); + } + + float sdTriPrism(inout vec3 p, inout vec2 h) + { + h.x *= 0.866025388240814208984375; + vec2 _768 = p.xy / vec2(h.x); + p = vec3(_768.x, _768.y, p.z); + p.x = abs(p.x) - 1.0; + p.y += 0.57735025882720947265625; + if ((p.x + (1.73205077648162841796875 * p.y)) > 0.0) + { + vec2 _806 = vec2(p.x - (1.73205077648162841796875 * p.y), ((-1.73205077648162841796875) * p.x) - p.y) * vec2(0.5); + p = vec3(_806.x, _806.y, p.z); + } + p.x -= clamp(p.x, -2.0, 0.0); + float _828 = (length(p.xy) * sign(-p.y)) * h.x; + float _835 = abs(p.z) - h.y; + return length(max(vec2(_828, _835), vec2(0.0))) + min(max(_828, _835), 0.0); + } + + float sdEllipsoid(vec3 p, vec3 r) + { + float _340 = length(p / r); + return (_340 * (_340 - 1.0)) / length(p / (r * r)); + } + + float ndot(vec2 a, vec2 b) + { + return (a.x * b.x) - (a.y * b.y); + } + + float sdRhombus(inout vec3 p, float la, float lb, float h, float ra) + { + p = abs(p); + vec2 _1509 = vec2(la, lb); + vec2 param = _1509; + vec2 param_1 = _1509 - (p.xz * 2.0); + float _1524 = clamp(ndot(param, param_1) / dot(_1509, _1509), -1.0, 1.0); + float _1558 = (length(p.xz - ((_1509 * 0.5) * vec2(1.0 - _1524, 1.0 + _1524))) * sign(((p.x * lb) + (p.z * la)) - (la * lb))) - ra; + float _1562 = p.y - h; + return min(max(_1558, _1562), 0.0) + length(max(vec2(_1558, _1562), vec2(0.0))); + } + + float sdOctogonPrism(inout vec3 p, float r, float h) + { + p = abs(p); + vec2 _496 = p.xy - (vec2(-0.92387950420379638671875, 0.3826834261417388916015625) * (2.0 * min(dot(vec2(-0.92387950420379638671875, 0.3826834261417388916015625), p.xy), 0.0))); + p = vec3(_496.x, _496.y, p.z); + vec2 _509 = p.xy - (vec2(0.92387950420379638671875, 0.3826834261417388916015625) * (2.0 * min(dot(vec2(0.92387950420379638671875, 0.3826834261417388916015625), p.xy), 0.0))); + p = vec3(_509.x, _509.y, p.z); + vec2 _525 = p.xy - vec2(clamp(p.x, (-0.4142135679721832275390625) * r, 0.4142135679721832275390625 * r), r); + p = vec3(_525.x, _525.y, p.z); + float _535 = length(p.xy) * sign(p.y); + float _539 = p.z - h; + return min(max(_535, _539), 0.0) + length(max(vec2(_535, _539), vec2(0.0))); + } + + float sdCylinder(vec3 p, vec3 a, vec3 b, float r) + { + vec3 _875 = p - a; + vec3 _879 = b - a; + float _883 = dot(_879, _879); + float _887 = dot(_875, _879); + float _900 = length((_875 * _883) - (_879 * _887)) - (r * _883); + float _904 = _883 * 0.5; + float _909 = abs(_887 - _904) - _904; + float _913 = _900 * _900; + float _919 = (_909 * _909) * _883; + float _925; + if (max(_900, _909) < 0.0) + { + _925 = -min(_913, _919); + } + else + { + _925 = ((_900 > 0.0) ? _913 : 0.0) + ((_909 > 0.0) ? _919 : 0.0); + } + return (sign(_925) * sqrt(abs(_925))) / _883; + } + + float sdCappedCone(vec3 p, vec3 a, vec3 b, float ra, float rb) + { + float _1120 = rb - ra; + float _1128 = dot(b - a, b - a); + float _1144 = dot(p - a, b - a); + float _1146 = _1144 / _1128; + float _1155 = sqrt(dot(p - a, p - a) - ((_1146 * _1146) * _1128)); + float _1164 = max(0.0, _1155 - ((_1146 < 0.5) ? ra : rb)); + float _1169 = abs(_1146 - 0.5) - 0.5; + float _1188 = clamp(((_1120 * (_1155 - ra)) + _1144) / ((_1120 * _1120) + _1128), 0.0, 1.0); + float _1196 = (_1155 - ra) - (_1188 * _1120); + float _1200 = _1146 - _1188; + return (((_1196 < 0.0) && (_1169 < 0.0)) ? (-1.0) : 1.0) * sqrt(min((_1164 * _1164) + ((_1169 * _1169) * _1128), (_1196 * _1196) + ((_1200 * _1200) * _1128))); + } + + float dot2(vec3 v) + { + return dot(v, v); + } + + float sdRoundCone(vec3 p, vec3 a, vec3 b, float r1, float r2) + { + vec3 _643 = b - a; + float _647 = dot(_643, _643); + float _651 = r1 - r2; + float _657 = _647 - (_651 * _651); + float _660 = 1.0 / _647; + vec3 _664 = p - a; + float _668 = dot(_664, _643); + float _672 = _668 - _647; + vec3 param = (_664 * _647) - (_643 * _668); + float _682 = dot2(param); + float _688 = (_668 * _668) * _647; + float _694 = (_672 * _672) * _647; + float _703 = ((sign(_651) * _651) * _651) * _682; + if (((sign(_672) * _657) * _694) > _703) + { + return (sqrt(_682 + _694) * _660) - r2; + } + if (((sign(_668) * _657) * _688) < _703) + { + return (sqrt(_682 + _688) * _660) - r1; + } + return ((sqrt((_682 * _657) * _660) + (_668 * _651)) * _660) - r1; + } + + float sdRoundCone(vec3 p, float r1, float r2, float h) + { + vec2 _587 = vec2(length(p.xz), p.y); + float _593 = (r1 - r2) / h; + float _599 = sqrt(1.0 - (_593 * _593)); + float _606 = dot(_587, vec2(-_593, _599)); + if (_606 < 0.0) + { + return length(_587) - r1; + } + if (_606 > (_599 * h)) + { + return length(_587 - vec2(0.0, h)) - r2; + } + return dot(_587, vec2(_599, _593)) - r1; + } + + vec2 map(vec3 pos) + { + vec2 res = vec2(10000000000.0, 0.0); + vec3 param = pos - vec3(-2.0, 0.25, 0.0); + float param_1 = 0.25; + vec2 param_2 = res; + vec2 param_3 = vec2(sdSphere(param, param_1), 26.8999996185302734375); + res = opU(param_2, param_3); + vec3 param_4 = pos - vec3(0.0, 0.300000011920928955078125, -1.0); + vec3 param_5 = vec3(0.3499999940395355224609375, 0.300000011920928955078125, 2.5); + if (sdBox(param_4, param_5) < res.x) + { + vec3 param_6 = pos - vec3(0.0, 0.25, 0.0); + vec3 param_7 = vec3(0.300000011920928955078125, 0.25, 0.20000000298023223876953125); + float param_8 = 0.02500000037252902984619140625; + float _1628 = sdBoundingBox(param_6, param_7, param_8); + vec2 param_9 = res; + vec2 param_10 = vec2(_1628, 16.8999996185302734375); + res = opU(param_9, param_10); + vec3 param_11 = (pos - vec3(0.0, 0.300000011920928955078125, 1.0)).xzy; + vec2 param_12 = vec2(0.25, 0.0500000007450580596923828125); + vec2 param_13 = res; + vec2 param_14 = vec2(sdTorus(param_11, param_12), 25.0); + res = opU(param_13, param_14); + vec3 param_15 = pos - vec3(0.0, 0.449999988079071044921875, -1.0); + vec2 param_16 = vec2(0.60000002384185791015625, 0.800000011920928955078125); + float param_17 = 0.449999988079071044921875; + vec2 param_18 = res; + vec2 param_19 = vec2(sdCone(param_15, param_16, param_17), 55.0); + res = opU(param_18, param_19); + vec3 param_20 = pos - vec3(0.0, 0.25, -2.0); + float param_21 = 0.25; + float param_22 = 0.25; + float param_23 = 0.100000001490116119384765625; + vec2 param_24 = res; + vec2 param_25 = vec2(sdCappedCone(param_20, param_21, param_22, param_23), 13.6700000762939453125); + res = opU(param_24, param_25); + vec3 param_26 = pos - vec3(0.0, 0.0, -3.0); + vec2 param_27 = vec2(0.60000002384185791015625, 0.800000011920928955078125); + float param_28 = 0.4000000059604644775390625; + vec2 param_29 = res; + vec2 param_30 = vec2(sdSolidAngle(param_26, param_27, param_28), 49.130001068115234375); + res = opU(param_29, param_30); + } + vec3 param_31 = pos - vec3(1.0, 0.300000011920928955078125, -1.0); + vec3 param_32 = vec3(0.3499999940395355224609375, 0.300000011920928955078125, 2.5); + if (sdBox(param_31, param_32) < res.x) + { + vec3 param_33 = (pos - vec3(1.0, 0.300000011920928955078125, 1.0)) * vec3(1.0, -1.0, 1.0); + vec2 param_34 = vec2(0.86602497100830078125, -0.5); + float param_35 = 0.25; + float param_36 = 0.0500000007450580596923828125; + float _1720 = sdCappedTorus(param_33, param_34, param_35, param_36); + vec2 param_37 = res; + vec2 param_38 = vec2(_1720, 8.5); + res = opU(param_37, param_38); + vec3 param_39 = pos - vec3(1.0, 0.25, 0.0); + vec3 param_40 = vec3(0.300000011920928955078125, 0.25, 0.100000001490116119384765625); + vec2 param_41 = res; + vec2 param_42 = vec2(sdBox(param_39, param_40), 3.0); + res = opU(param_41, param_42); + vec3 param_43 = pos - vec3(1.0, 0.0, -1.0); + vec3 param_44 = vec3(-0.100000001490116119384765625, 0.100000001490116119384765625, -0.100000001490116119384765625); + vec3 param_45 = vec3(0.20000000298023223876953125, 0.4000000059604644775390625, 0.20000000298023223876953125); + float param_46 = 0.100000001490116119384765625; + vec2 param_47 = res; + vec2 param_48 = vec2(sdCapsule(param_43, param_44, param_45, param_46), 31.8999996185302734375); + res = opU(param_47, param_48); + vec3 param_49 = pos - vec3(1.0, 0.25, -2.0); + vec2 param_50 = vec2(0.1500000059604644775390625, 0.25); + vec2 param_51 = res; + vec2 param_52 = vec2(sdCylinder(param_49, param_50), 8.0); + res = opU(param_51, param_52); + vec3 param_53 = pos - vec3(1.0, 0.20000000298023223876953125, -3.0); + vec2 param_54 = vec2(0.20000000298023223876953125, 0.0500000007450580596923828125); + float _1776 = sdHexPrism(param_53, param_54); + vec2 param_55 = res; + vec2 param_56 = vec2(_1776, 18.3999996185302734375); + res = opU(param_55, param_56); + } + vec3 param_57 = pos - vec3(-1.0, 0.3499999940395355224609375, -1.0); + vec3 param_58 = vec3(0.3499999940395355224609375, 0.3499999940395355224609375, 2.5); + if (sdBox(param_57, param_58) < res.x) + { + vec3 param_59 = pos - vec3(-1.0, -0.60000002384185791015625, -3.0); + float param_60 = 1.0; + float _1801 = sdPyramid(param_59, param_60); + vec2 param_61 = res; + vec2 param_62 = vec2(_1801, 13.56000041961669921875); + res = opU(param_61, param_62); + vec3 param_63 = pos - vec3(-1.0, 0.1500000059604644775390625, -2.0); + float param_64 = 0.3499999940395355224609375; + float _1813 = sdOctahedron(param_63, param_64); + vec2 param_65 = res; + vec2 param_66 = vec2(_1813, 23.5599994659423828125); + res = opU(param_65, param_66); + vec3 param_67 = pos - vec3(-1.0, 0.1500000059604644775390625, -1.0); + vec2 param_68 = vec2(0.300000011920928955078125, 0.0500000007450580596923828125); + float _1826 = sdTriPrism(param_67, param_68); + vec2 param_69 = res; + vec2 param_70 = vec2(_1826, 43.5); + res = opU(param_69, param_70); + vec3 param_71 = pos - vec3(-1.0, 0.25, 0.0); + vec3 param_72 = vec3(0.20000000298023223876953125, 0.25, 0.0500000007450580596923828125); + vec2 param_73 = res; + vec2 param_74 = vec2(sdEllipsoid(param_71, param_72), 43.1699981689453125); + res = opU(param_73, param_74); + vec3 param_75 = (pos - vec3(-1.0, 0.3400000035762786865234375, 1.0)).xzy; + float param_76 = 0.1500000059604644775390625; + float param_77 = 0.25; + float param_78 = 0.039999999105930328369140625; + float param_79 = 0.07999999821186065673828125; + float _1858 = sdRhombus(param_75, param_76, param_77, param_78, param_79); + vec2 param_80 = res; + vec2 param_81 = vec2(_1858, 17.0); + res = opU(param_80, param_81); + } + vec3 param_82 = pos - vec3(2.0, 0.300000011920928955078125, -1.0); + vec3 param_83 = vec3(0.3499999940395355224609375, 0.300000011920928955078125, 2.5); + if (sdBox(param_82, param_83) < res.x) + { + vec3 param_84 = pos - vec3(2.0, 0.20000000298023223876953125, -3.0); + float param_85 = 0.20000000298023223876953125; + float param_86 = 0.0500000007450580596923828125; + float _1882 = sdOctogonPrism(param_84, param_85, param_86); + vec2 param_87 = res; + vec2 param_88 = vec2(_1882, 51.799999237060546875); + res = opU(param_87, param_88); + vec3 param_89 = pos - vec3(2.0, 0.1500000059604644775390625, -2.0); + vec3 param_90 = vec3(0.100000001490116119384765625, -0.100000001490116119384765625, 0.0); + vec3 param_91 = vec3(-0.20000000298023223876953125, 0.3499999940395355224609375, 0.100000001490116119384765625); + float param_92 = 0.07999999821186065673828125; + vec2 param_93 = res; + vec2 param_94 = vec2(sdCylinder(param_89, param_90, param_91, param_92), 31.200000762939453125); + res = opU(param_93, param_94); + vec3 param_95 = pos - vec3(2.0, 0.100000001490116119384765625, -1.0); + vec3 param_96 = vec3(0.100000001490116119384765625, 0.0, 0.0); + vec3 param_97 = vec3(-0.20000000298023223876953125, 0.4000000059604644775390625, 0.100000001490116119384765625); + float param_98 = 0.1500000059604644775390625; + float param_99 = 0.0500000007450580596923828125; + vec2 param_100 = res; + vec2 param_101 = vec2(sdCappedCone(param_95, param_96, param_97, param_98, param_99), 46.09999847412109375); + res = opU(param_100, param_101); + vec3 param_102 = pos - vec3(2.0, 0.1500000059604644775390625, 0.0); + vec3 param_103 = vec3(0.100000001490116119384765625, 0.0, 0.0); + vec3 param_104 = vec3(-0.100000001490116119384765625, 0.3499999940395355224609375, 0.100000001490116119384765625); + float param_105 = 0.1500000059604644775390625; + float param_106 = 0.0500000007450580596923828125; + vec2 param_107 = res; + vec2 param_108 = vec2(sdRoundCone(param_102, param_103, param_104, param_105, param_106), 51.700000762939453125); + res = opU(param_107, param_108); + vec3 param_109 = pos - vec3(2.0, 0.20000000298023223876953125, 1.0); + float param_110 = 0.20000000298023223876953125; + float param_111 = 0.100000001490116119384765625; + float param_112 = 0.300000011920928955078125; + vec2 param_113 = res; + vec2 param_114 = vec2(sdRoundCone(param_109, param_110, param_111, param_112), 37.0); + res = opU(param_113, param_114); + } + return res; + } + + vec2 raycast(vec3 ro, vec3 rd) + { + vec2 res = vec2(-1.0); + float tmin = 1.0; + float tmax = 20.0; + float _2009 = (-ro.y) / rd.y; + if (_2009 > 0.0) + { + tmax = min(tmax, _2009); + res = vec2(_2009, 1.0); + } + vec3 param = ro - vec3(0.0, 0.4000000059604644775390625, -0.5); + vec3 param_1 = rd; + vec3 param_2 = vec3(2.5, 0.4099999964237213134765625, 3.0); + vec2 _2029 = iBox(param, param_1, param_2); + float _2031 = _2029.x; + float _2033 = _2029.y; + bool _2034 = _2031 < _2033; + bool _2040; + if (_2034) + { + _2040 = _2033 > 0.0; + } + else + { + _2040 = _2034; + } + bool _2047; + if (_2040) + { + _2047 = _2031 < tmax; + } + else + { + _2047 = _2040; + } + if (_2047) + { + float _2052 = tmin; + float _2053 = max(_2031, _2052); + tmin = _2053; + tmax = min(_2033, tmax); + float t = _2053; + for (int i = 0; (i < 70) && (t < tmax); i++) + { + vec3 param_3 = ro + (rd * t); + vec2 _2083 = map(param_3); + float _2085 = _2083.x; + if (abs(_2085) < (9.9999997473787516355514526367188e-05 * t)) + { + res = vec2(t, _2083.y); + break; + } + t += _2085; + } + } + return res; + } + + vec3 calcNormal(vec3 pos) + { + vec3 n = vec3(0.0); + for (int i = min(int(fs_params[1].y), 0); i < 4; i++) + { + vec3 _2221 = ((vec3(float(((i + 3) >> 1) & 1), float((i >> 1) & 1), float(i & 1)) * 2.0) - vec3(1.0)) * 0.577300012111663818359375; + vec3 param = pos + (_2221 * 0.0005000000237487256526947021484375); + n += (_2221 * map(param).x); + } + return normalize(n); + } + + float checkersGradBox(vec2 p, vec2 dpdx, vec2 dpdy) + { + vec2 _2309 = (abs(dpdx) + abs(dpdy)) + vec2(0.001000000047497451305389404296875); + vec2 _2313 = _2309 * 0.5; + vec2 _2332 = ((abs(fract((p - _2313) * 0.5) - vec2(0.5)) - abs(fract((p + _2313) * 0.5) - vec2(0.5))) * 2.0) / _2309; + return 0.5 - ((0.5 * _2332.x) * _2332.y); + } + + float calcAO(vec3 pos, vec3 nor) + { + float occ = 0.0; + float sca = 1.0; + for (int i = min(int(fs_params[1].y), 0); i < 5; i++) + { + float _2263 = 0.00999999977648258209228515625 + (float(i) * 0.02999999932944774627685546875); + vec3 param = pos + (nor * _2263); + float _2276 = sca; + float _2278 = occ; + float _2279 = _2278 + ((_2263 - map(param).x) * _2276); + occ = _2279; + sca = _2276 * 0.949999988079071044921875; + if (_2279 > 0.3499999940395355224609375) + { + break; + } + } + return clamp(1.0 - (3.0 * occ), 0.0, 1.0) * (0.5 + (0.5 * nor.y)); + } + + float calcSoftshadow(vec3 ro, vec3 rd, float mint, inout float tmax) + { + float _2114 = (0.800000011920928955078125 - ro.y) / rd.y; + if (_2114 > 0.0) + { + tmax = min(tmax, _2114); + } + float res = 1.0; + float t = mint; + for (int i = min(int(fs_params[1].y), 0); i < 24; i++) + { + vec3 param = ro + (rd * t); + vec2 _2150 = map(param); + float _2151 = _2150.x; + float _2155 = t; + float _2157 = clamp((8.0 * _2151) / _2155, 0.0, 1.0); + float _2158 = res; + float _2166 = min(_2158, (_2157 * _2157) * (3.0 - (2.0 * _2157))); + res = _2166; + float _2171 = _2155 + clamp(_2151, 0.0199999995529651641845703125, 0.20000000298023223876953125); + t = _2171; + if ((_2166 < 0.0040000001899898052215576171875) || (_2171 > tmax)) + { + break; + } + } + return clamp(res, 0.0, 1.0); + } + + vec3 render(vec3 ro, vec3 rd, vec3 rdx, vec3 rdy) + { + vec3 col = vec3(0.699999988079071044921875, 0.699999988079071044921875, 0.89999997615814208984375) - vec3(max(rd.y, 0.0) * 0.300000011920928955078125); + vec3 param = ro; + vec3 param_1 = rd; + vec2 _2357 = raycast(param, param_1); + float _2360 = _2357.x; + float _2363 = _2357.y; + if (_2363 > (-0.5)) + { + vec3 _2373 = ro + (rd * _2360); + bool _2377 = _2363 < 1.5; + vec3 _2378; + if (_2377) + { + _2378 = vec3(0.0, 1.0, 0.0); + } + else + { + vec3 param_2 = _2373; + _2378 = calcNormal(param_2); + } + vec3 _2390 = reflect(rd, _2378); + col = vec3(0.20000000298023223876953125) + (sin(vec3(_2363 * 2.0) + vec3(0.0, 1.0, 2.0)) * 0.20000000298023223876953125); + float ks = 1.0; + if (_2377) + { + vec2 param_3 = _2373.xz * 3.0; + vec2 param_4 = (((rd / vec3(rd.y)) - (rdx / vec3(rdx.y))) * ro.y).xz * 3.0; + vec2 param_5 = (((rd / vec3(rd.y)) - (rdy / vec3(rdy.y))) * ro.y).xz * 3.0; + col = vec3(0.1500000059604644775390625) + (vec3(0.0500000007450580596923828125) * checkersGradBox(param_3, param_4, param_5)); + ks = 0.4000000059604644775390625; + } + vec3 param_6 = _2373; + vec3 param_7 = _2378; + float _2459 = calcAO(param_6, param_7); + vec3 lin = vec3(0.0); + vec3 _2470 = normalize(vec3(-0.56980288028717041015625, 0.455842316150665283203125, -0.683763444423675537109375) - rd); + float dif = clamp(dot(_2378, vec3(-0.56980288028717041015625, 0.455842316150665283203125, -0.683763444423675537109375)), 0.0, 1.0); + vec3 param_8 = _2373; + vec3 param_9 = vec3(-0.56980288028717041015625, 0.455842316150665283203125, -0.683763444423675537109375); + float param_10 = 0.0199999995529651641845703125; + float param_11 = 2.5; + float _2482 = calcSoftshadow(param_8, param_9, param_10, param_11); + float _2483 = dif; + float _2484 = _2483 * _2482; + dif = _2484; + lin = (lin + (((col * 2.2000000476837158203125) * _2484) * vec3(1.2999999523162841796875, 1.0, 0.699999988079071044921875))) + ((vec3(1.2999999523162841796875, 1.0, 0.699999988079071044921875) * (5.0 * ((pow(clamp(dot(_2378, _2470), 0.0, 1.0), 16.0) * _2484) * (0.039999999105930328369140625 + (0.959999978542327880859375 * pow(clamp(1.0 - dot(_2470, vec3(-0.56980288028717041015625, 0.455842316150665283203125, -0.683763444423675537109375)), 0.0, 1.0), 5.0)))))) * ks); + float _2533 = sqrt(clamp(0.5 + (0.5 * _2378.y), 0.0, 1.0)) * _2459; + float spe = (smoothstep(-0.20000000298023223876953125, 0.20000000298023223876953125, _2390.y) * _2533) * (0.039999999105930328369140625 + (0.959999978542327880859375 * pow(clamp(1.0 + dot(_2378, rd), 0.0, 1.0), 5.0))); + vec3 param_12 = _2373; + vec3 param_13 = _2390; + float param_14 = 0.0199999995529651641845703125; + float param_15 = 2.5; + float _2557 = calcSoftshadow(param_12, param_13, param_14, param_15); + float _2558 = spe; + float _2559 = _2558 * _2557; + spe = _2559; + vec3 _2567 = lin; + vec3 _2618 = (((_2567 + (((col * 0.60000002384185791015625) * _2533) * vec3(0.4000000059604644775390625, 0.60000002384185791015625, 1.14999997615814208984375))) + ((vec3(0.4000000059604644775390625, 0.60000002384185791015625, 1.2999999523162841796875) * (2.0 * _2559)) * ks)) + (((col * 0.550000011920928955078125) * ((clamp(dot(_2378, vec3(0.6401844024658203125, 0.0, 0.76822125911712646484375)), 0.0, 1.0) * clamp(1.0 - _2373.y, 0.0, 1.0)) * _2459)) * vec3(0.25))) + ((col * 0.25) * (pow(clamp(1.0 + dot(_2378, rd), 0.0, 1.0), 2.0) * _2459)); + lin = _2618; + col = mix(_2618, vec3(0.699999988079071044921875, 0.699999988079071044921875, 0.89999997615814208984375), vec3(1.0 - exp((((-9.9999997473787516355514526367188e-05) * _2360) * _2360) * _2360))); + } + return clamp(col, vec3(0.0), vec3(1.0)); + } + + vec4 mainImage(vec2 fragCoord) + { + vec2 _2686 = fs_params[0].zw / fs_params[0].xy; + float _2705 = (0.100000001490116119384765625 * (32.0 + (fs_params[1].x * 1.5))) + (7.0 * _2686.x); + vec3 _2721 = vec3(0.5, -0.5, -0.60000002384185791015625) + vec3(4.5 * cos(_2705), 1.2999999523162841796875 + (2.0 * _2686.y), 4.5 * sin(_2705)); + vec3 param = _2721; + vec3 param_1 = vec3(0.5, -0.5, -0.60000002384185791015625); + float param_2 = 0.0; + mat3 _2729 = setCamera(param, param_1, param_2); + vec3 tot = vec3(0.0); + vec2 _2739 = vec2(fs_params[0].y); + vec3 param_3 = _2721; + vec3 param_4 = _2729 * normalize(vec3(((fragCoord * 2.0) - fs_params[0].xy) / _2739, 2.5)); + vec3 param_5 = _2729 * normalize(vec3((((fragCoord + vec2(1.0, 0.0)) * 2.0) - fs_params[0].xy) / _2739, 2.5)); + vec3 param_6 = _2729 * normalize(vec3((((fragCoord + vec2(0.0, 1.0)) * 2.0) - fs_params[0].xy) / _2739, 2.5)); + vec3 _2804 = tot; + vec3 _2805 = _2804 + pow(render(param_3, param_4, param_5, param_6), vec3(0.4544999897480010986328125)); + tot = _2805; + return vec4(_2805, 1.0); + } + + void main() + { + vec2 param = uv * fs_params[0].xy; + frag_color = ((texture(tex, uv) * color) * 9.9999997473787516355514526367188e-06) + mainImage(param); + } + +*/ +static const char fs_source_glsl330[28396] = { + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e, + 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x73,0x5f,0x70,0x61, + 0x72,0x61,0x6d,0x73,0x5b,0x32,0x5d,0x3b,0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d, + 0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x3b,0x0a, + 0x0a,0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a, + 0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f, + 0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29, + 0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63, + 0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x6d,0x61,0x74,0x33,0x20,0x73,0x65,0x74,0x43, + 0x61,0x6d,0x65,0x72,0x61,0x28,0x76,0x65,0x63,0x33,0x20,0x72,0x6f,0x2c,0x20,0x76, + 0x65,0x63,0x33,0x20,0x74,0x61,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x63,0x72, + 0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x36, + 0x34,0x36,0x20,0x3d,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28,0x74, + 0x61,0x20,0x2d,0x20,0x72,0x6f,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x5f,0x32,0x36,0x35,0x37,0x20,0x3d,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c, + 0x69,0x7a,0x65,0x28,0x63,0x72,0x6f,0x73,0x73,0x28,0x5f,0x32,0x36,0x34,0x36,0x2c, + 0x20,0x76,0x65,0x63,0x33,0x28,0x73,0x69,0x6e,0x28,0x63,0x72,0x29,0x2c,0x20,0x63, + 0x6f,0x73,0x28,0x63,0x72,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x61,0x74,0x33,0x28, + 0x5f,0x32,0x36,0x35,0x37,0x2c,0x20,0x63,0x72,0x6f,0x73,0x73,0x28,0x5f,0x32,0x36, + 0x35,0x37,0x2c,0x20,0x5f,0x32,0x36,0x34,0x36,0x29,0x2c,0x20,0x5f,0x32,0x36,0x34, + 0x36,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x76,0x65,0x63,0x32,0x20,0x69,0x42,0x6f,0x78, + 0x28,0x76,0x65,0x63,0x33,0x20,0x72,0x6f,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72, + 0x64,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72,0x61,0x64,0x29,0x0a,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x31,0x39,0x35,0x39,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x33,0x28,0x31,0x2e,0x30,0x29,0x20,0x2f,0x20,0x72,0x64,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x31,0x39,0x36,0x38,0x20,0x3d, + 0x20,0x61,0x62,0x73,0x28,0x5f,0x31,0x39,0x35,0x39,0x29,0x20,0x2a,0x20,0x72,0x61, + 0x64,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x31,0x39,0x37, + 0x31,0x20,0x3d,0x20,0x2d,0x28,0x5f,0x31,0x39,0x35,0x39,0x20,0x2a,0x20,0x72,0x6f, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x31,0x39,0x37, + 0x33,0x20,0x3d,0x20,0x5f,0x31,0x39,0x37,0x31,0x20,0x2d,0x20,0x5f,0x31,0x39,0x36, + 0x38,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x31,0x39,0x37, + 0x38,0x20,0x3d,0x20,0x5f,0x31,0x39,0x37,0x31,0x20,0x2b,0x20,0x5f,0x31,0x39,0x36, + 0x38,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x65, + 0x63,0x32,0x28,0x6d,0x61,0x78,0x28,0x6d,0x61,0x78,0x28,0x5f,0x31,0x39,0x37,0x33, + 0x2e,0x78,0x2c,0x20,0x5f,0x31,0x39,0x37,0x33,0x2e,0x79,0x29,0x2c,0x20,0x5f,0x31, + 0x39,0x37,0x33,0x2e,0x7a,0x29,0x2c,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x69,0x6e,0x28, + 0x5f,0x31,0x39,0x37,0x38,0x2e,0x78,0x2c,0x20,0x5f,0x31,0x39,0x37,0x38,0x2e,0x79, + 0x29,0x2c,0x20,0x5f,0x31,0x39,0x37,0x38,0x2e,0x7a,0x29,0x29,0x3b,0x0a,0x7d,0x0a, + 0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x53,0x70,0x68,0x65,0x72,0x65,0x28, + 0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6c,0x65, + 0x6e,0x67,0x74,0x68,0x28,0x70,0x29,0x20,0x2d,0x20,0x73,0x3b,0x0a,0x7d,0x0a,0x0a, + 0x76,0x65,0x63,0x32,0x20,0x6f,0x70,0x55,0x28,0x76,0x65,0x63,0x32,0x20,0x64,0x31, + 0x2c,0x20,0x76,0x65,0x63,0x32,0x20,0x64,0x32,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x62,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x35,0x38,0x35,0x20,0x3d,0x20,0x62, + 0x76,0x65,0x63,0x32,0x28,0x64,0x31,0x2e,0x78,0x20,0x3c,0x20,0x64,0x32,0x2e,0x78, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x65, + 0x63,0x32,0x28,0x5f,0x31,0x35,0x38,0x35,0x2e,0x78,0x20,0x3f,0x20,0x64,0x31,0x2e, + 0x78,0x20,0x3a,0x20,0x64,0x32,0x2e,0x78,0x2c,0x20,0x5f,0x31,0x35,0x38,0x35,0x2e, + 0x79,0x20,0x3f,0x20,0x64,0x31,0x2e,0x79,0x20,0x3a,0x20,0x64,0x32,0x2e,0x79,0x29, + 0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x42,0x6f,0x78, + 0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x62,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x34,0x30, + 0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x29,0x20,0x2d,0x20,0x62,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61, + 0x78,0x28,0x5f,0x32,0x34,0x30,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x28,0x5f,0x32, + 0x34,0x30,0x2e,0x79,0x2c,0x20,0x5f,0x32,0x34,0x30,0x2e,0x7a,0x29,0x29,0x2c,0x20, + 0x30,0x2e,0x30,0x29,0x20,0x2b,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61, + 0x78,0x28,0x5f,0x32,0x34,0x30,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30, + 0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64, + 0x42,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x42,0x6f,0x78,0x28,0x69,0x6e,0x6f,0x75, + 0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x62, + 0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x65,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x70,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x29,0x20,0x2d,0x20,0x62,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x37,0x31,0x20,0x3d, + 0x20,0x61,0x62,0x73,0x28,0x70,0x20,0x2b,0x20,0x76,0x65,0x63,0x33,0x28,0x65,0x29, + 0x29,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x65,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x37,0x35,0x20,0x3d,0x20,0x5f,0x32, + 0x37,0x31,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x32,0x37,0x37,0x20,0x3d,0x20,0x5f,0x32,0x37,0x31,0x2e,0x7a,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x39,0x33,0x20,0x3d,0x20, + 0x5f,0x32,0x37,0x31,0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x69,0x6e,0x28,0x6c,0x65,0x6e,0x67,0x74, + 0x68,0x28,0x6d,0x61,0x78,0x28,0x76,0x65,0x63,0x33,0x28,0x70,0x2e,0x78,0x2c,0x20, + 0x5f,0x32,0x37,0x35,0x2c,0x20,0x5f,0x32,0x37,0x37,0x29,0x2c,0x20,0x76,0x65,0x63, + 0x33,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x20,0x2b,0x20,0x6d,0x69,0x6e,0x28,0x6d, + 0x61,0x78,0x28,0x70,0x2e,0x78,0x2c,0x20,0x6d,0x61,0x78,0x28,0x5f,0x32,0x37,0x35, + 0x2c,0x20,0x5f,0x32,0x37,0x37,0x29,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x2c,0x20, + 0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x76,0x65,0x63,0x33,0x28, + 0x5f,0x32,0x39,0x33,0x2c,0x20,0x70,0x2e,0x79,0x2c,0x20,0x5f,0x32,0x37,0x37,0x29, + 0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x20,0x2b,0x20, + 0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x5f,0x32,0x39,0x33,0x2c,0x20,0x6d,0x61, + 0x78,0x28,0x70,0x2e,0x79,0x2c,0x20,0x5f,0x32,0x37,0x37,0x29,0x29,0x2c,0x20,0x30, + 0x2e,0x30,0x29,0x29,0x2c,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78, + 0x28,0x76,0x65,0x63,0x33,0x28,0x5f,0x32,0x39,0x33,0x2c,0x20,0x5f,0x32,0x37,0x35, + 0x2c,0x20,0x70,0x2e,0x7a,0x29,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30, + 0x29,0x29,0x29,0x20,0x2b,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x5f,0x32, + 0x39,0x33,0x2c,0x20,0x6d,0x61,0x78,0x28,0x5f,0x32,0x37,0x35,0x2c,0x20,0x70,0x2e, + 0x7a,0x29,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x54,0x6f,0x72,0x75,0x73,0x28,0x76,0x65,0x63, + 0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x29,0x0a,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68, + 0x28,0x76,0x65,0x63,0x32,0x28,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78, + 0x7a,0x29,0x20,0x2d,0x20,0x74,0x2e,0x78,0x2c,0x20,0x70,0x2e,0x79,0x29,0x29,0x20, + 0x2d,0x20,0x74,0x2e,0x79,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x73,0x64,0x43,0x6f,0x6e,0x65,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x76, + 0x65,0x63,0x32,0x20,0x63,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x29,0x0a, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x39,0x36,0x35,0x20, + 0x3d,0x20,0x28,0x76,0x65,0x63,0x32,0x28,0x63,0x2e,0x78,0x2c,0x20,0x2d,0x63,0x2e, + 0x79,0x29,0x20,0x2a,0x20,0x68,0x29,0x20,0x2f,0x20,0x76,0x65,0x63,0x32,0x28,0x63, + 0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x39,0x36,0x39,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78, + 0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x39,0x37, + 0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x39,0x36,0x39,0x2c,0x20,0x70, + 0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x39, + 0x38,0x35,0x20,0x3d,0x20,0x5f,0x39,0x37,0x32,0x20,0x2d,0x20,0x28,0x5f,0x39,0x36, + 0x35,0x20,0x2a,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28,0x5f,0x39, + 0x37,0x32,0x2c,0x20,0x5f,0x39,0x36,0x35,0x29,0x20,0x2f,0x20,0x64,0x6f,0x74,0x28, + 0x5f,0x39,0x36,0x35,0x2c,0x20,0x5f,0x39,0x36,0x35,0x29,0x2c,0x20,0x30,0x2e,0x30, + 0x2c,0x20,0x31,0x2e,0x30,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x39,0x39,0x32,0x20,0x3d,0x20,0x5f,0x39,0x36,0x35,0x2e,0x78, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x39,0x39,0x37,0x20, + 0x3d,0x20,0x5f,0x39,0x37,0x32,0x20,0x2d,0x20,0x28,0x5f,0x39,0x36,0x35,0x20,0x2a, + 0x20,0x76,0x65,0x63,0x32,0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x5f,0x39,0x36,0x39, + 0x20,0x2f,0x20,0x5f,0x39,0x39,0x32,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e, + 0x30,0x29,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x30,0x30,0x30,0x20,0x3d,0x20,0x5f,0x39,0x36, + 0x35,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x31,0x30,0x30,0x31,0x20,0x3d,0x20,0x73,0x69,0x67,0x6e,0x28,0x5f,0x31,0x30,0x30, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73, + 0x71,0x72,0x74,0x28,0x6d,0x69,0x6e,0x28,0x64,0x6f,0x74,0x28,0x5f,0x39,0x38,0x35, + 0x2c,0x20,0x5f,0x39,0x38,0x35,0x29,0x2c,0x20,0x64,0x6f,0x74,0x28,0x5f,0x39,0x39, + 0x37,0x2c,0x20,0x5f,0x39,0x39,0x37,0x29,0x29,0x29,0x20,0x2a,0x20,0x73,0x69,0x67, + 0x6e,0x28,0x6d,0x61,0x78,0x28,0x5f,0x31,0x30,0x30,0x31,0x20,0x2a,0x20,0x28,0x28, + 0x5f,0x39,0x36,0x39,0x20,0x2a,0x20,0x5f,0x31,0x30,0x30,0x30,0x29,0x20,0x2d,0x20, + 0x28,0x70,0x2e,0x79,0x20,0x2a,0x20,0x5f,0x39,0x39,0x32,0x29,0x29,0x2c,0x20,0x5f, + 0x31,0x30,0x30,0x31,0x20,0x2a,0x20,0x28,0x70,0x2e,0x79,0x20,0x2d,0x20,0x5f,0x31, + 0x30,0x30,0x30,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x64,0x6f,0x74,0x32,0x28,0x76,0x65,0x63,0x32,0x20,0x76,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x64,0x6f,0x74,0x28,0x76, + 0x2c,0x20,0x76,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73, + 0x64,0x43,0x61,0x70,0x70,0x65,0x64,0x43,0x6f,0x6e,0x65,0x28,0x76,0x65,0x63,0x33, + 0x20,0x70,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x2c,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x72,0x31,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x32,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x30, + 0x34,0x32,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78,0x7a, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x30,0x34, + 0x35,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x30,0x34,0x32,0x2c,0x20, + 0x70,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f, + 0x31,0x30,0x34,0x39,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x72,0x32,0x2c,0x20, + 0x68,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x30, + 0x35,0x36,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x72,0x32,0x20,0x2d,0x20,0x72, + 0x31,0x2c,0x20,0x32,0x2e,0x30,0x20,0x2a,0x20,0x68,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x30,0x37,0x34,0x20,0x3d,0x20,0x61, + 0x62,0x73,0x28,0x70,0x2e,0x79,0x29,0x20,0x2d,0x20,0x68,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x5f,0x31, + 0x30,0x35,0x36,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31, + 0x30,0x39,0x32,0x20,0x3d,0x20,0x28,0x5f,0x31,0x30,0x34,0x35,0x20,0x2d,0x20,0x5f, + 0x31,0x30,0x34,0x39,0x29,0x20,0x2b,0x20,0x28,0x5f,0x31,0x30,0x35,0x36,0x20,0x2a, + 0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28,0x5f,0x31,0x30,0x34,0x39, + 0x20,0x2d,0x20,0x5f,0x31,0x30,0x34,0x35,0x2c,0x20,0x5f,0x31,0x30,0x35,0x36,0x29, + 0x20,0x2f,0x20,0x64,0x6f,0x74,0x32,0x28,0x70,0x61,0x72,0x61,0x6d,0x29,0x2c,0x20, + 0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x31,0x30,0x39,0x36,0x20,0x3d,0x20,0x5f,0x31,0x30, + 0x39,0x32,0x2e,0x78,0x20,0x3c,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x31,0x31,0x30,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x69,0x66,0x20,0x28,0x5f,0x31,0x30,0x39,0x36,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x31,0x31,0x30,0x32,0x20,0x3d, + 0x20,0x5f,0x31,0x30,0x37,0x34,0x20,0x3c,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20, + 0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x31,0x31,0x30,0x32, + 0x20,0x3d,0x20,0x5f,0x31,0x30,0x39,0x36,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x30,0x34,0x32,0x20,0x2d,0x20, + 0x6d,0x69,0x6e,0x28,0x5f,0x31,0x30,0x34,0x32,0x2c,0x20,0x28,0x70,0x2e,0x79,0x20, + 0x3c,0x20,0x30,0x2e,0x30,0x29,0x20,0x3f,0x20,0x72,0x31,0x20,0x3a,0x20,0x72,0x32, + 0x29,0x2c,0x20,0x5f,0x31,0x30,0x37,0x34,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x20,0x3d,0x20,0x5f,0x31, + 0x30,0x39,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x28,0x5f,0x31,0x31,0x30,0x32,0x20,0x3f,0x20,0x28,0x2d,0x31,0x2e,0x30,0x29,0x20, + 0x3a,0x20,0x31,0x2e,0x30,0x29,0x20,0x2a,0x20,0x73,0x71,0x72,0x74,0x28,0x6d,0x69, + 0x6e,0x28,0x64,0x6f,0x74,0x32,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x29,0x2c, + 0x20,0x64,0x6f,0x74,0x32,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x29,0x29,0x29, + 0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x53,0x6f,0x6c, + 0x69,0x64,0x41,0x6e,0x67,0x6c,0x65,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x6f,0x73, + 0x2c,0x20,0x76,0x65,0x63,0x32,0x20,0x63,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x61,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x32,0x33,0x35,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70, + 0x6f,0x73,0x2e,0x78,0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x5f,0x31,0x32,0x33,0x38,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31, + 0x32,0x33,0x35,0x2c,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x61,0x78,0x28,0x6c,0x65,0x6e,0x67, + 0x74,0x68,0x28,0x5f,0x31,0x32,0x33,0x38,0x29,0x20,0x2d,0x20,0x72,0x61,0x2c,0x20, + 0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x5f,0x31,0x32,0x33,0x38,0x20,0x2d,0x20,0x28, + 0x63,0x20,0x2a,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28,0x5f,0x31, + 0x32,0x33,0x38,0x2c,0x20,0x63,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x72,0x61, + 0x29,0x29,0x29,0x20,0x2a,0x20,0x73,0x69,0x67,0x6e,0x28,0x28,0x63,0x2e,0x79,0x20, + 0x2a,0x20,0x5f,0x31,0x32,0x33,0x35,0x29,0x20,0x2d,0x20,0x28,0x63,0x2e,0x78,0x20, + 0x2a,0x20,0x70,0x6f,0x73,0x2e,0x79,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x43,0x61,0x70,0x70,0x65,0x64,0x54,0x6f,0x72, + 0x75,0x73,0x28,0x69,0x6e,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c, + 0x20,0x76,0x65,0x63,0x32,0x20,0x73,0x63,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x61,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x62,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x70,0x2e,0x78,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x2e, + 0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33, + 0x38,0x39,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x73,0x63,0x2e, + 0x79,0x20,0x2a,0x20,0x70,0x2e,0x78,0x29,0x20,0x3e,0x20,0x28,0x73,0x63,0x2e,0x78, + 0x20,0x2a,0x20,0x70,0x2e,0x79,0x29,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x33,0x38,0x39,0x20,0x3d,0x20,0x64,0x6f, + 0x74,0x28,0x70,0x2e,0x78,0x79,0x2c,0x20,0x73,0x63,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x33,0x38,0x39,0x20,0x3d, + 0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78,0x79,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x73,0x71,0x72,0x74,0x28,0x28,0x64,0x6f,0x74,0x28,0x70,0x2c,0x20,0x70,0x29,0x20, + 0x2b,0x20,0x28,0x72,0x61,0x20,0x2a,0x20,0x72,0x61,0x29,0x29,0x20,0x2d,0x20,0x28, + 0x28,0x32,0x2e,0x30,0x20,0x2a,0x20,0x72,0x61,0x29,0x20,0x2a,0x20,0x5f,0x33,0x38, + 0x39,0x29,0x29,0x20,0x2d,0x20,0x72,0x62,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x73,0x64,0x43,0x61,0x70,0x73,0x75,0x6c,0x65,0x28,0x76,0x65,0x63, + 0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x61,0x2c,0x20,0x76,0x65,0x63, + 0x33,0x20,0x62,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x35,0x35,0x37,0x20,0x3d,0x20, + 0x70,0x20,0x2d,0x20,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20, + 0x5f,0x35,0x36,0x31,0x20,0x3d,0x20,0x62,0x20,0x2d,0x20,0x61,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28, + 0x5f,0x35,0x35,0x37,0x20,0x2d,0x20,0x28,0x5f,0x35,0x36,0x31,0x20,0x2a,0x20,0x63, + 0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28,0x5f,0x35,0x35,0x37,0x2c,0x20,0x5f, + 0x35,0x36,0x31,0x29,0x20,0x2f,0x20,0x64,0x6f,0x74,0x28,0x5f,0x35,0x36,0x31,0x2c, + 0x20,0x5f,0x35,0x36,0x31,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30, + 0x29,0x29,0x29,0x20,0x2d,0x20,0x72,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x73,0x64,0x43,0x79,0x6c,0x69,0x6e,0x64,0x65,0x72,0x28,0x76,0x65,0x63, + 0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x32,0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x38,0x35,0x38,0x20,0x3d,0x20,0x61, + 0x62,0x73,0x28,0x76,0x65,0x63,0x32,0x28,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70, + 0x2e,0x78,0x7a,0x29,0x2c,0x20,0x70,0x2e,0x79,0x29,0x29,0x20,0x2d,0x20,0x68,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x69,0x6e,0x28, + 0x6d,0x61,0x78,0x28,0x5f,0x38,0x35,0x38,0x2e,0x78,0x2c,0x20,0x5f,0x38,0x35,0x38, + 0x2e,0x79,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x20,0x2b,0x20,0x6c,0x65,0x6e,0x67, + 0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x5f,0x38,0x35,0x38,0x2c,0x20,0x76,0x65,0x63, + 0x32,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x73,0x64,0x48,0x65,0x78,0x50,0x72,0x69,0x73,0x6d,0x28,0x69,0x6e, + 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x32, + 0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x61,0x62, + 0x73,0x28,0x70,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f, + 0x34,0x33,0x35,0x20,0x3d,0x20,0x70,0x2e,0x78,0x79,0x20,0x2d,0x20,0x28,0x76,0x65, + 0x63,0x32,0x28,0x2d,0x30,0x2e,0x38,0x36,0x36,0x30,0x32,0x35,0x33,0x38,0x38,0x32, + 0x34,0x30,0x38,0x31,0x34,0x32,0x30,0x38,0x39,0x38,0x34,0x33,0x37,0x35,0x2c,0x20, + 0x30,0x2e,0x35,0x29,0x20,0x2a,0x20,0x28,0x32,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x69, + 0x6e,0x28,0x64,0x6f,0x74,0x28,0x76,0x65,0x63,0x32,0x28,0x2d,0x30,0x2e,0x38,0x36, + 0x36,0x30,0x32,0x35,0x33,0x38,0x38,0x32,0x34,0x30,0x38,0x31,0x34,0x32,0x30,0x38, + 0x39,0x38,0x34,0x33,0x37,0x35,0x2c,0x20,0x30,0x2e,0x35,0x29,0x2c,0x20,0x70,0x2e, + 0x78,0x79,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x70,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x34,0x33,0x35,0x2e,0x78, + 0x2c,0x20,0x5f,0x34,0x33,0x35,0x2e,0x79,0x2c,0x20,0x70,0x2e,0x7a,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x34,0x36,0x33,0x20,0x3d, + 0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78,0x79,0x20,0x2d,0x20,0x76, + 0x65,0x63,0x32,0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x70,0x2e,0x78,0x2c,0x20,0x28, + 0x2d,0x30,0x2e,0x35,0x37,0x37,0x33,0x35,0x30,0x30,0x32,0x30,0x34,0x30,0x38,0x36, + 0x33,0x30,0x33,0x37,0x31,0x30,0x39,0x33,0x37,0x35,0x29,0x20,0x2a,0x20,0x68,0x2e, + 0x78,0x2c,0x20,0x30,0x2e,0x35,0x37,0x37,0x33,0x35,0x30,0x30,0x32,0x30,0x34,0x30, + 0x38,0x36,0x33,0x30,0x33,0x37,0x31,0x30,0x39,0x33,0x37,0x35,0x20,0x2a,0x20,0x68, + 0x2e,0x78,0x29,0x2c,0x20,0x68,0x2e,0x78,0x29,0x29,0x20,0x2a,0x20,0x73,0x69,0x67, + 0x6e,0x28,0x70,0x2e,0x79,0x20,0x2d,0x20,0x68,0x2e,0x78,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x34,0x36,0x38,0x20,0x3d,0x20,0x70, + 0x2e,0x7a,0x20,0x2d,0x20,0x68,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65, + 0x74,0x75,0x72,0x6e,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x5f,0x34,0x36, + 0x33,0x2c,0x20,0x5f,0x34,0x36,0x38,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x20,0x2b, + 0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x76,0x65,0x63,0x32, + 0x28,0x5f,0x34,0x36,0x33,0x2c,0x20,0x5f,0x34,0x36,0x38,0x29,0x2c,0x20,0x76,0x65, + 0x63,0x32,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x73,0x64,0x50,0x79,0x72,0x61,0x6d,0x69,0x64,0x28,0x69,0x6e, + 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x5f,0x31,0x33,0x35,0x30,0x20,0x3d,0x20,0x68,0x20,0x2a,0x20,0x68,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x33,0x35,0x32,0x20, + 0x3d,0x20,0x5f,0x31,0x33,0x35,0x30,0x20,0x2b,0x20,0x30,0x2e,0x32,0x35,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x33,0x35,0x35,0x20,0x3d, + 0x20,0x61,0x62,0x73,0x28,0x70,0x2e,0x78,0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x70,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x31,0x33,0x35,0x35,0x2e,0x78, + 0x2c,0x20,0x70,0x2e,0x79,0x2c,0x20,0x5f,0x31,0x33,0x35,0x35,0x2e,0x79,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x31,0x33,0x36,0x33,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x70,0x2e,0x7a,0x20,0x3e,0x20,0x70, + 0x2e,0x78,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x5f,0x31,0x33,0x36,0x33,0x20,0x3d,0x20,0x70,0x2e,0x7a,0x78,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20, + 0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x31,0x33, + 0x36,0x33,0x20,0x3d,0x20,0x70,0x2e,0x78,0x7a,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d, + 0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x31, + 0x33,0x36,0x33,0x2e,0x78,0x2c,0x20,0x70,0x2e,0x79,0x2c,0x20,0x5f,0x31,0x33,0x36, + 0x33,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f, + 0x31,0x33,0x37,0x37,0x20,0x3d,0x20,0x70,0x2e,0x78,0x7a,0x20,0x2d,0x20,0x76,0x65, + 0x63,0x32,0x28,0x30,0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d, + 0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x31,0x33,0x37,0x37,0x2e,0x78,0x2c,0x20,0x70, + 0x2e,0x79,0x2c,0x20,0x5f,0x31,0x33,0x37,0x37,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x33,0x39,0x30,0x20,0x3d,0x20, + 0x28,0x68,0x20,0x2a,0x20,0x70,0x2e,0x79,0x29,0x20,0x2d,0x20,0x28,0x30,0x2e,0x35, + 0x20,0x2a,0x20,0x70,0x2e,0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x31,0x33,0x39,0x38,0x20,0x3d,0x20,0x28,0x68,0x20,0x2a,0x20, + 0x70,0x2e,0x78,0x29,0x20,0x2b,0x20,0x28,0x30,0x2e,0x35,0x20,0x2a,0x20,0x70,0x2e, + 0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31, + 0x34,0x30,0x33,0x20,0x3d,0x20,0x2d,0x70,0x2e,0x7a,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x34,0x31,0x35,0x20,0x3d,0x20,0x63,0x6c, + 0x61,0x6d,0x70,0x28,0x28,0x5f,0x31,0x33,0x39,0x30,0x20,0x2d,0x20,0x28,0x30,0x2e, + 0x35,0x20,0x2a,0x20,0x70,0x2e,0x7a,0x29,0x29,0x20,0x2f,0x20,0x28,0x5f,0x31,0x33, + 0x35,0x30,0x20,0x2b,0x20,0x30,0x2e,0x35,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20, + 0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x34,0x32,0x31,0x20,0x3d,0x20,0x70,0x2e,0x7a,0x20,0x2b,0x20,0x6d,0x61, + 0x78,0x28,0x5f,0x31,0x34,0x30,0x33,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x34,0x34,0x30,0x20,0x3d, + 0x20,0x70,0x2e,0x7a,0x20,0x2b,0x20,0x28,0x30,0x2e,0x35,0x20,0x2a,0x20,0x5f,0x31, + 0x34,0x31,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x34,0x35,0x33,0x20,0x3d,0x20,0x5f,0x31,0x33,0x39,0x30,0x20,0x2d,0x20, + 0x28,0x5f,0x31,0x33,0x35,0x32,0x20,0x2a,0x20,0x5f,0x31,0x34,0x31,0x35,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x34,0x37,0x36, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x6d,0x69,0x6e,0x28,0x5f,0x31, + 0x33,0x39,0x30,0x2c,0x20,0x28,0x5f,0x31,0x34,0x30,0x33,0x20,0x2a,0x20,0x5f,0x31, + 0x33,0x35,0x32,0x29,0x20,0x2d,0x20,0x28,0x5f,0x31,0x33,0x39,0x30,0x20,0x2a,0x20, + 0x30,0x2e,0x35,0x29,0x29,0x20,0x3e,0x20,0x30,0x2e,0x30,0x29,0x0a,0x20,0x20,0x20, + 0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x31,0x34,0x37,0x36, + 0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20, + 0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x5f,0x31,0x34,0x37,0x36,0x20,0x3d,0x20,0x6d,0x69,0x6e, + 0x28,0x28,0x28,0x5f,0x31,0x33,0x35,0x32,0x20,0x2a,0x20,0x5f,0x31,0x34,0x32,0x31, + 0x29,0x20,0x2a,0x20,0x5f,0x31,0x34,0x32,0x31,0x29,0x20,0x2b,0x20,0x28,0x5f,0x31, + 0x33,0x39,0x30,0x20,0x2a,0x20,0x5f,0x31,0x33,0x39,0x30,0x29,0x2c,0x20,0x28,0x28, + 0x5f,0x31,0x33,0x35,0x32,0x20,0x2a,0x20,0x5f,0x31,0x34,0x34,0x30,0x29,0x20,0x2a, + 0x20,0x5f,0x31,0x34,0x34,0x30,0x29,0x20,0x2b,0x20,0x28,0x5f,0x31,0x34,0x35,0x33, + 0x20,0x2a,0x20,0x5f,0x31,0x34,0x35,0x33,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x71,0x72, + 0x74,0x28,0x28,0x5f,0x31,0x34,0x37,0x36,0x20,0x2b,0x20,0x28,0x5f,0x31,0x33,0x39, + 0x38,0x20,0x2a,0x20,0x5f,0x31,0x33,0x39,0x38,0x29,0x29,0x20,0x2f,0x20,0x5f,0x31, + 0x33,0x35,0x32,0x29,0x20,0x2a,0x20,0x73,0x69,0x67,0x6e,0x28,0x6d,0x61,0x78,0x28, + 0x5f,0x31,0x33,0x39,0x38,0x2c,0x20,0x2d,0x70,0x2e,0x79,0x29,0x29,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x4f,0x63,0x74,0x61,0x68,0x65, + 0x64,0x72,0x6f,0x6e,0x28,0x69,0x6e,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20, + 0x70,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x29,0x0a,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x70,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x32,0x38,0x35,0x20,0x3d,0x20, + 0x28,0x28,0x70,0x2e,0x78,0x20,0x2b,0x20,0x70,0x2e,0x79,0x29,0x20,0x2b,0x20,0x70, + 0x2e,0x7a,0x29,0x20,0x2d,0x20,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x71,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x33,0x2e, + 0x30,0x20,0x2a,0x20,0x70,0x2e,0x78,0x29,0x20,0x3c,0x20,0x5f,0x31,0x32,0x38,0x35, + 0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x71,0x20,0x3d,0x20,0x70,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20, + 0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x33,0x2e,0x30,0x20,0x2a,0x20,0x70, + 0x2e,0x79,0x29,0x20,0x3c,0x20,0x5f,0x31,0x32,0x38,0x35,0x29,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x71,0x20,0x3d,0x20,0x70,0x2e,0x79,0x7a,0x78,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28, + 0x33,0x2e,0x30,0x20,0x2a,0x20,0x70,0x2e,0x7a,0x29,0x20,0x3c,0x20,0x5f,0x31,0x32, + 0x38,0x35,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x71,0x20,0x3d,0x20,0x70,0x2e,0x7a,0x78,0x79,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e, + 0x20,0x5f,0x31,0x32,0x38,0x35,0x20,0x2a,0x20,0x30,0x2e,0x35,0x37,0x37,0x33,0x35, + 0x30,0x32,0x35,0x38,0x38,0x32,0x37,0x32,0x30,0x39,0x34,0x37,0x32,0x36,0x35,0x36, + 0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x7d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20, + 0x7d,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x33,0x33, + 0x30,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x30,0x2e,0x35,0x20,0x2a,0x20, + 0x28,0x28,0x71,0x2e,0x7a,0x20,0x2d,0x20,0x71,0x2e,0x79,0x29,0x20,0x2b,0x20,0x73, + 0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x73,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x76,0x65, + 0x63,0x33,0x28,0x71,0x2e,0x78,0x2c,0x20,0x28,0x71,0x2e,0x79,0x20,0x2d,0x20,0x73, + 0x29,0x20,0x2b,0x20,0x5f,0x31,0x33,0x33,0x30,0x2c,0x20,0x71,0x2e,0x7a,0x20,0x2d, + 0x20,0x5f,0x31,0x33,0x33,0x30,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x73,0x64,0x54,0x72,0x69,0x50,0x72,0x69,0x73,0x6d,0x28,0x69,0x6e, + 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x69,0x6e,0x6f,0x75, + 0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20, + 0x68,0x2e,0x78,0x20,0x2a,0x3d,0x20,0x30,0x2e,0x38,0x36,0x36,0x30,0x32,0x35,0x33, + 0x38,0x38,0x32,0x34,0x30,0x38,0x31,0x34,0x32,0x30,0x38,0x39,0x38,0x34,0x33,0x37, + 0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x37,0x36,0x38, + 0x20,0x3d,0x20,0x70,0x2e,0x78,0x79,0x20,0x2f,0x20,0x76,0x65,0x63,0x32,0x28,0x68, + 0x2e,0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x33,0x28,0x5f,0x37,0x36,0x38,0x2e,0x78,0x2c,0x20,0x5f,0x37,0x36,0x38,0x2e,0x79, + 0x2c,0x20,0x70,0x2e,0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x70,0x2e,0x78,0x20, + 0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x2e,0x78,0x29,0x20,0x2d,0x20,0x31,0x2e,0x30, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x70,0x2e,0x79,0x20,0x2b,0x3d,0x20,0x30,0x2e,0x35, + 0x37,0x37,0x33,0x35,0x30,0x32,0x35,0x38,0x38,0x32,0x37,0x32,0x30,0x39,0x34,0x37, + 0x32,0x36,0x35,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28, + 0x28,0x70,0x2e,0x78,0x20,0x2b,0x20,0x28,0x31,0x2e,0x37,0x33,0x32,0x30,0x35,0x30, + 0x37,0x37,0x36,0x34,0x38,0x31,0x36,0x32,0x38,0x34,0x31,0x37,0x39,0x36,0x38,0x37, + 0x35,0x20,0x2a,0x20,0x70,0x2e,0x79,0x29,0x29,0x20,0x3e,0x20,0x30,0x2e,0x30,0x29, + 0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x5f,0x38,0x30,0x36,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28, + 0x70,0x2e,0x78,0x20,0x2d,0x20,0x28,0x31,0x2e,0x37,0x33,0x32,0x30,0x35,0x30,0x37, + 0x37,0x36,0x34,0x38,0x31,0x36,0x32,0x38,0x34,0x31,0x37,0x39,0x36,0x38,0x37,0x35, + 0x20,0x2a,0x20,0x70,0x2e,0x79,0x29,0x2c,0x20,0x28,0x28,0x2d,0x31,0x2e,0x37,0x33, + 0x32,0x30,0x35,0x30,0x37,0x37,0x36,0x34,0x38,0x31,0x36,0x32,0x38,0x34,0x31,0x37, + 0x39,0x36,0x38,0x37,0x35,0x29,0x20,0x2a,0x20,0x70,0x2e,0x78,0x29,0x20,0x2d,0x20, + 0x70,0x2e,0x79,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x35,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x5f,0x38,0x30,0x36,0x2e,0x78,0x2c,0x20,0x5f,0x38,0x30,0x36,0x2e, + 0x79,0x2c,0x20,0x70,0x2e,0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20, + 0x20,0x20,0x20,0x70,0x2e,0x78,0x20,0x2d,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28, + 0x70,0x2e,0x78,0x2c,0x20,0x2d,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x38,0x32,0x38,0x20, + 0x3d,0x20,0x28,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78,0x79,0x29,0x20, + 0x2a,0x20,0x73,0x69,0x67,0x6e,0x28,0x2d,0x70,0x2e,0x79,0x29,0x29,0x20,0x2a,0x20, + 0x68,0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x38,0x33,0x35,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x70,0x2e,0x7a,0x29,0x20,0x2d, + 0x20,0x68,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e, + 0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x76,0x65,0x63,0x32, + 0x28,0x5f,0x38,0x32,0x38,0x2c,0x20,0x5f,0x38,0x33,0x35,0x29,0x2c,0x20,0x76,0x65, + 0x63,0x32,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x20,0x2b,0x20,0x6d,0x69,0x6e,0x28, + 0x6d,0x61,0x78,0x28,0x5f,0x38,0x32,0x38,0x2c,0x20,0x5f,0x38,0x33,0x35,0x29,0x2c, + 0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x73,0x64,0x45,0x6c,0x6c,0x69,0x70,0x73,0x6f,0x69,0x64,0x28,0x76,0x65,0x63,0x33, + 0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x33,0x34,0x30,0x20,0x3d,0x20,0x6c, + 0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x20,0x2f,0x20,0x72,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x5f,0x33,0x34,0x30,0x20,0x2a, + 0x20,0x28,0x5f,0x33,0x34,0x30,0x20,0x2d,0x20,0x31,0x2e,0x30,0x29,0x29,0x20,0x2f, + 0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x20,0x2f,0x20,0x28,0x72,0x20,0x2a, + 0x20,0x72,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6e, + 0x64,0x6f,0x74,0x28,0x76,0x65,0x63,0x32,0x20,0x61,0x2c,0x20,0x76,0x65,0x63,0x32, + 0x20,0x62,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e, + 0x20,0x28,0x61,0x2e,0x78,0x20,0x2a,0x20,0x62,0x2e,0x78,0x29,0x20,0x2d,0x20,0x28, + 0x61,0x2e,0x79,0x20,0x2a,0x20,0x62,0x2e,0x79,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x52,0x68,0x6f,0x6d,0x62,0x75,0x73,0x28,0x69, + 0x6e,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x6c,0x61,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6c,0x62,0x2c, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x61,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x61,0x62, + 0x73,0x28,0x70,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f, + 0x31,0x35,0x30,0x39,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x6c,0x61,0x2c,0x20, + 0x6c,0x62,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x20,0x3d,0x20,0x5f,0x31,0x35,0x30,0x39,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x20,0x3d,0x20, + 0x5f,0x31,0x35,0x30,0x39,0x20,0x2d,0x20,0x28,0x70,0x2e,0x78,0x7a,0x20,0x2a,0x20, + 0x32,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x35,0x32,0x34,0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x6e,0x64, + 0x6f,0x74,0x28,0x70,0x61,0x72,0x61,0x6d,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x29,0x20,0x2f,0x20,0x64,0x6f,0x74,0x28,0x5f,0x31,0x35,0x30,0x39,0x2c,0x20, + 0x5f,0x31,0x35,0x30,0x39,0x29,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x2c,0x20,0x31,0x2e, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31, + 0x35,0x35,0x38,0x20,0x3d,0x20,0x28,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e, + 0x78,0x7a,0x20,0x2d,0x20,0x28,0x28,0x5f,0x31,0x35,0x30,0x39,0x20,0x2a,0x20,0x30, + 0x2e,0x35,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x32,0x28,0x31,0x2e,0x30,0x20,0x2d, + 0x20,0x5f,0x31,0x35,0x32,0x34,0x2c,0x20,0x31,0x2e,0x30,0x20,0x2b,0x20,0x5f,0x31, + 0x35,0x32,0x34,0x29,0x29,0x29,0x20,0x2a,0x20,0x73,0x69,0x67,0x6e,0x28,0x28,0x28, + 0x70,0x2e,0x78,0x20,0x2a,0x20,0x6c,0x62,0x29,0x20,0x2b,0x20,0x28,0x70,0x2e,0x7a, + 0x20,0x2a,0x20,0x6c,0x61,0x29,0x29,0x20,0x2d,0x20,0x28,0x6c,0x61,0x20,0x2a,0x20, + 0x6c,0x62,0x29,0x29,0x29,0x20,0x2d,0x20,0x72,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x35,0x36,0x32,0x20,0x3d,0x20,0x70,0x2e, + 0x79,0x20,0x2d,0x20,0x68,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72, + 0x6e,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28,0x5f,0x31,0x35,0x35,0x38,0x2c, + 0x20,0x5f,0x31,0x35,0x36,0x32,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x20,0x2b,0x20, + 0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x76,0x65,0x63,0x32,0x28, + 0x5f,0x31,0x35,0x35,0x38,0x2c,0x20,0x5f,0x31,0x35,0x36,0x32,0x29,0x2c,0x20,0x76, + 0x65,0x63,0x32,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x4f,0x63,0x74,0x6f,0x67,0x6f,0x6e,0x50,0x72, + 0x69,0x73,0x6d,0x28,0x69,0x6e,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x61,0x62, + 0x73,0x28,0x70,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f, + 0x34,0x39,0x36,0x20,0x3d,0x20,0x70,0x2e,0x78,0x79,0x20,0x2d,0x20,0x28,0x76,0x65, + 0x63,0x32,0x28,0x2d,0x30,0x2e,0x39,0x32,0x33,0x38,0x37,0x39,0x35,0x30,0x34,0x32, + 0x30,0x33,0x37,0x39,0x36,0x33,0x38,0x36,0x37,0x31,0x38,0x37,0x35,0x2c,0x20,0x30, + 0x2e,0x33,0x38,0x32,0x36,0x38,0x33,0x34,0x32,0x36,0x31,0x34,0x31,0x37,0x33,0x38, + 0x38,0x39,0x31,0x36,0x30,0x31,0x35,0x36,0x32,0x35,0x29,0x20,0x2a,0x20,0x28,0x32, + 0x2e,0x30,0x20,0x2a,0x20,0x6d,0x69,0x6e,0x28,0x64,0x6f,0x74,0x28,0x76,0x65,0x63, + 0x32,0x28,0x2d,0x30,0x2e,0x39,0x32,0x33,0x38,0x37,0x39,0x35,0x30,0x34,0x32,0x30, + 0x33,0x37,0x39,0x36,0x33,0x38,0x36,0x37,0x31,0x38,0x37,0x35,0x2c,0x20,0x30,0x2e, + 0x33,0x38,0x32,0x36,0x38,0x33,0x34,0x32,0x36,0x31,0x34,0x31,0x37,0x33,0x38,0x38, + 0x39,0x31,0x36,0x30,0x31,0x35,0x36,0x32,0x35,0x29,0x2c,0x20,0x70,0x2e,0x78,0x79, + 0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x70, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x34,0x39,0x36,0x2e,0x78,0x2c,0x20, + 0x5f,0x34,0x39,0x36,0x2e,0x79,0x2c,0x20,0x70,0x2e,0x7a,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x35,0x30,0x39,0x20,0x3d,0x20,0x70,0x2e, + 0x78,0x79,0x20,0x2d,0x20,0x28,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x39,0x32,0x33, + 0x38,0x37,0x39,0x35,0x30,0x34,0x32,0x30,0x33,0x37,0x39,0x36,0x33,0x38,0x36,0x37, + 0x31,0x38,0x37,0x35,0x2c,0x20,0x30,0x2e,0x33,0x38,0x32,0x36,0x38,0x33,0x34,0x32, + 0x36,0x31,0x34,0x31,0x37,0x33,0x38,0x38,0x39,0x31,0x36,0x30,0x31,0x35,0x36,0x32, + 0x35,0x29,0x20,0x2a,0x20,0x28,0x32,0x2e,0x30,0x20,0x2a,0x20,0x6d,0x69,0x6e,0x28, + 0x64,0x6f,0x74,0x28,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x39,0x32,0x33,0x38,0x37, + 0x39,0x35,0x30,0x34,0x32,0x30,0x33,0x37,0x39,0x36,0x33,0x38,0x36,0x37,0x31,0x38, + 0x37,0x35,0x2c,0x20,0x30,0x2e,0x33,0x38,0x32,0x36,0x38,0x33,0x34,0x32,0x36,0x31, + 0x34,0x31,0x37,0x33,0x38,0x38,0x39,0x31,0x36,0x30,0x31,0x35,0x36,0x32,0x35,0x29, + 0x2c,0x20,0x70,0x2e,0x78,0x79,0x29,0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x5f,0x35, + 0x30,0x39,0x2e,0x78,0x2c,0x20,0x5f,0x35,0x30,0x39,0x2e,0x79,0x2c,0x20,0x70,0x2e, + 0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x35,0x32, + 0x35,0x20,0x3d,0x20,0x70,0x2e,0x78,0x79,0x20,0x2d,0x20,0x76,0x65,0x63,0x32,0x28, + 0x63,0x6c,0x61,0x6d,0x70,0x28,0x70,0x2e,0x78,0x2c,0x20,0x28,0x2d,0x30,0x2e,0x34, + 0x31,0x34,0x32,0x31,0x33,0x35,0x36,0x37,0x39,0x37,0x32,0x31,0x38,0x33,0x32,0x32, + 0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x29,0x20,0x2a,0x20,0x72,0x2c,0x20,0x30, + 0x2e,0x34,0x31,0x34,0x32,0x31,0x33,0x35,0x36,0x37,0x39,0x37,0x32,0x31,0x38,0x33, + 0x32,0x32,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x20,0x2a,0x20,0x72,0x29,0x2c, + 0x20,0x72,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x70,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x33,0x28,0x5f,0x35,0x32,0x35,0x2e,0x78,0x2c,0x20,0x5f,0x35,0x32,0x35,0x2e,0x79, + 0x2c,0x20,0x70,0x2e,0x7a,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x5f,0x35,0x33,0x35,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28, + 0x70,0x2e,0x78,0x79,0x29,0x20,0x2a,0x20,0x73,0x69,0x67,0x6e,0x28,0x70,0x2e,0x79, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x35,0x33, + 0x39,0x20,0x3d,0x20,0x70,0x2e,0x7a,0x20,0x2d,0x20,0x68,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,0x69,0x6e,0x28,0x6d,0x61,0x78,0x28, + 0x5f,0x35,0x33,0x35,0x2c,0x20,0x5f,0x35,0x33,0x39,0x29,0x2c,0x20,0x30,0x2e,0x30, + 0x29,0x20,0x2b,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x6d,0x61,0x78,0x28,0x76, + 0x65,0x63,0x32,0x28,0x5f,0x35,0x33,0x35,0x2c,0x20,0x5f,0x35,0x33,0x39,0x29,0x2c, + 0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a, + 0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x43,0x79,0x6c,0x69,0x6e,0x64,0x65, + 0x72,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x61, + 0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x62,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x38, + 0x37,0x35,0x20,0x3d,0x20,0x70,0x20,0x2d,0x20,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x76,0x65,0x63,0x33,0x20,0x5f,0x38,0x37,0x39,0x20,0x3d,0x20,0x62,0x20,0x2d,0x20, + 0x61,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x38,0x38, + 0x33,0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x5f,0x38,0x37,0x39,0x2c,0x20,0x5f,0x38, + 0x37,0x39,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x38,0x38,0x37,0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x5f,0x38,0x37,0x35,0x2c,0x20, + 0x5f,0x38,0x37,0x39,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x5f,0x39,0x30,0x30,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x28, + 0x5f,0x38,0x37,0x35,0x20,0x2a,0x20,0x5f,0x38,0x38,0x33,0x29,0x20,0x2d,0x20,0x28, + 0x5f,0x38,0x37,0x39,0x20,0x2a,0x20,0x5f,0x38,0x38,0x37,0x29,0x29,0x20,0x2d,0x20, + 0x28,0x72,0x20,0x2a,0x20,0x5f,0x38,0x38,0x33,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x39,0x30,0x34,0x20,0x3d,0x20,0x5f,0x38,0x38, + 0x33,0x20,0x2a,0x20,0x30,0x2e,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x39,0x30,0x39,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x5f,0x38, + 0x38,0x37,0x20,0x2d,0x20,0x5f,0x39,0x30,0x34,0x29,0x20,0x2d,0x20,0x5f,0x39,0x30, + 0x34,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x39,0x31, + 0x33,0x20,0x3d,0x20,0x5f,0x39,0x30,0x30,0x20,0x2a,0x20,0x5f,0x39,0x30,0x30,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x39,0x31,0x39,0x20, + 0x3d,0x20,0x28,0x5f,0x39,0x30,0x39,0x20,0x2a,0x20,0x5f,0x39,0x30,0x39,0x29,0x20, + 0x2a,0x20,0x5f,0x38,0x38,0x33,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x5f,0x39,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28, + 0x6d,0x61,0x78,0x28,0x5f,0x39,0x30,0x30,0x2c,0x20,0x5f,0x39,0x30,0x39,0x29,0x20, + 0x3c,0x20,0x30,0x2e,0x30,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x5f,0x39,0x32,0x35,0x20,0x3d,0x20,0x2d,0x6d,0x69,0x6e, + 0x28,0x5f,0x39,0x31,0x33,0x2c,0x20,0x5f,0x39,0x31,0x39,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20, + 0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x39,0x32,0x35,0x20, + 0x3d,0x20,0x28,0x28,0x5f,0x39,0x30,0x30,0x20,0x3e,0x20,0x30,0x2e,0x30,0x29,0x20, + 0x3f,0x20,0x5f,0x39,0x31,0x33,0x20,0x3a,0x20,0x30,0x2e,0x30,0x29,0x20,0x2b,0x20, + 0x28,0x28,0x5f,0x39,0x30,0x39,0x20,0x3e,0x20,0x30,0x2e,0x30,0x29,0x20,0x3f,0x20, + 0x5f,0x39,0x31,0x39,0x20,0x3a,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x73, + 0x69,0x67,0x6e,0x28,0x5f,0x39,0x32,0x35,0x29,0x20,0x2a,0x20,0x73,0x71,0x72,0x74, + 0x28,0x61,0x62,0x73,0x28,0x5f,0x39,0x32,0x35,0x29,0x29,0x29,0x20,0x2f,0x20,0x5f, + 0x38,0x38,0x33,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64, + 0x43,0x61,0x70,0x70,0x65,0x64,0x43,0x6f,0x6e,0x65,0x28,0x76,0x65,0x63,0x33,0x20, + 0x70,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x61,0x2c,0x20,0x76,0x65,0x63,0x33,0x20, + 0x62,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x61,0x2c,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x72,0x62,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x31,0x31,0x32,0x30,0x20,0x3d,0x20,0x72,0x62,0x20,0x2d,0x20, + 0x72,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31, + 0x31,0x32,0x38,0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x62,0x20,0x2d,0x20,0x61,0x2c, + 0x20,0x62,0x20,0x2d,0x20,0x61,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x31,0x31,0x34,0x34,0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x70, + 0x20,0x2d,0x20,0x61,0x2c,0x20,0x62,0x20,0x2d,0x20,0x61,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x31,0x34,0x36,0x20,0x3d,0x20, + 0x5f,0x31,0x31,0x34,0x34,0x20,0x2f,0x20,0x5f,0x31,0x31,0x32,0x38,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x31,0x35,0x35,0x20,0x3d, + 0x20,0x73,0x71,0x72,0x74,0x28,0x64,0x6f,0x74,0x28,0x70,0x20,0x2d,0x20,0x61,0x2c, + 0x20,0x70,0x20,0x2d,0x20,0x61,0x29,0x20,0x2d,0x20,0x28,0x28,0x5f,0x31,0x31,0x34, + 0x36,0x20,0x2a,0x20,0x5f,0x31,0x31,0x34,0x36,0x29,0x20,0x2a,0x20,0x5f,0x31,0x31, + 0x32,0x38,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x31,0x36,0x34,0x20,0x3d,0x20,0x6d,0x61,0x78,0x28,0x30,0x2e,0x30,0x2c, + 0x20,0x5f,0x31,0x31,0x35,0x35,0x20,0x2d,0x20,0x28,0x28,0x5f,0x31,0x31,0x34,0x36, + 0x20,0x3c,0x20,0x30,0x2e,0x35,0x29,0x20,0x3f,0x20,0x72,0x61,0x20,0x3a,0x20,0x72, + 0x62,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x31,0x31,0x36,0x39,0x20,0x3d,0x20,0x61,0x62,0x73,0x28,0x5f,0x31,0x31,0x34,0x36, + 0x20,0x2d,0x20,0x30,0x2e,0x35,0x29,0x20,0x2d,0x20,0x30,0x2e,0x35,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x31,0x38,0x38,0x20,0x3d, + 0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x28,0x28,0x5f,0x31,0x31,0x32,0x30,0x20,0x2a, + 0x20,0x28,0x5f,0x31,0x31,0x35,0x35,0x20,0x2d,0x20,0x72,0x61,0x29,0x29,0x20,0x2b, + 0x20,0x5f,0x31,0x31,0x34,0x34,0x29,0x20,0x2f,0x20,0x28,0x28,0x5f,0x31,0x31,0x32, + 0x30,0x20,0x2a,0x20,0x5f,0x31,0x31,0x32,0x30,0x29,0x20,0x2b,0x20,0x5f,0x31,0x31, + 0x32,0x38,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x31,0x39,0x36,0x20, + 0x3d,0x20,0x28,0x5f,0x31,0x31,0x35,0x35,0x20,0x2d,0x20,0x72,0x61,0x29,0x20,0x2d, + 0x20,0x28,0x5f,0x31,0x31,0x38,0x38,0x20,0x2a,0x20,0x5f,0x31,0x31,0x32,0x30,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x32,0x30, + 0x30,0x20,0x3d,0x20,0x5f,0x31,0x31,0x34,0x36,0x20,0x2d,0x20,0x5f,0x31,0x31,0x38, + 0x38,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28, + 0x28,0x5f,0x31,0x31,0x39,0x36,0x20,0x3c,0x20,0x30,0x2e,0x30,0x29,0x20,0x26,0x26, + 0x20,0x28,0x5f,0x31,0x31,0x36,0x39,0x20,0x3c,0x20,0x30,0x2e,0x30,0x29,0x29,0x20, + 0x3f,0x20,0x28,0x2d,0x31,0x2e,0x30,0x29,0x20,0x3a,0x20,0x31,0x2e,0x30,0x29,0x20, + 0x2a,0x20,0x73,0x71,0x72,0x74,0x28,0x6d,0x69,0x6e,0x28,0x28,0x5f,0x31,0x31,0x36, + 0x34,0x20,0x2a,0x20,0x5f,0x31,0x31,0x36,0x34,0x29,0x20,0x2b,0x20,0x28,0x28,0x5f, + 0x31,0x31,0x36,0x39,0x20,0x2a,0x20,0x5f,0x31,0x31,0x36,0x39,0x29,0x20,0x2a,0x20, + 0x5f,0x31,0x31,0x32,0x38,0x29,0x2c,0x20,0x28,0x5f,0x31,0x31,0x39,0x36,0x20,0x2a, + 0x20,0x5f,0x31,0x31,0x39,0x36,0x29,0x20,0x2b,0x20,0x28,0x28,0x5f,0x31,0x32,0x30, + 0x30,0x20,0x2a,0x20,0x5f,0x31,0x32,0x30,0x30,0x29,0x20,0x2a,0x20,0x5f,0x31,0x31, + 0x32,0x38,0x29,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x64,0x6f,0x74,0x32,0x28,0x76,0x65,0x63,0x33,0x20,0x76,0x29,0x0a,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x64,0x6f,0x74,0x28,0x76,0x2c, + 0x20,0x76,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64, + 0x52,0x6f,0x75,0x6e,0x64,0x43,0x6f,0x6e,0x65,0x28,0x76,0x65,0x63,0x33,0x20,0x70, + 0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x61,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x62, + 0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x31,0x2c,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x72,0x32,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33, + 0x20,0x5f,0x36,0x34,0x33,0x20,0x3d,0x20,0x62,0x20,0x2d,0x20,0x61,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x34,0x37,0x20,0x3d,0x20, + 0x64,0x6f,0x74,0x28,0x5f,0x36,0x34,0x33,0x2c,0x20,0x5f,0x36,0x34,0x33,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x35,0x31,0x20, + 0x3d,0x20,0x72,0x31,0x20,0x2d,0x20,0x72,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x35,0x37,0x20,0x3d,0x20,0x5f,0x36,0x34,0x37, + 0x20,0x2d,0x20,0x28,0x5f,0x36,0x35,0x31,0x20,0x2a,0x20,0x5f,0x36,0x35,0x31,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x36,0x30, + 0x20,0x3d,0x20,0x31,0x2e,0x30,0x20,0x2f,0x20,0x5f,0x36,0x34,0x37,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x36,0x36,0x34,0x20,0x3d,0x20,0x70, + 0x20,0x2d,0x20,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x36,0x36,0x38,0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x5f,0x36,0x36,0x34,0x2c, + 0x20,0x5f,0x36,0x34,0x33,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x5f,0x36,0x37,0x32,0x20,0x3d,0x20,0x5f,0x36,0x36,0x38,0x20,0x2d,0x20, + 0x5f,0x36,0x34,0x37,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x28,0x5f,0x36,0x36,0x34,0x20,0x2a,0x20,0x5f, + 0x36,0x34,0x37,0x29,0x20,0x2d,0x20,0x28,0x5f,0x36,0x34,0x33,0x20,0x2a,0x20,0x5f, + 0x36,0x36,0x38,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x36,0x38,0x32,0x20,0x3d,0x20,0x64,0x6f,0x74,0x32,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36, + 0x38,0x38,0x20,0x3d,0x20,0x28,0x5f,0x36,0x36,0x38,0x20,0x2a,0x20,0x5f,0x36,0x36, + 0x38,0x29,0x20,0x2a,0x20,0x5f,0x36,0x34,0x37,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x39,0x34,0x20,0x3d,0x20,0x28,0x5f,0x36,0x37, + 0x32,0x20,0x2a,0x20,0x5f,0x36,0x37,0x32,0x29,0x20,0x2a,0x20,0x5f,0x36,0x34,0x37, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x37,0x30,0x33, + 0x20,0x3d,0x20,0x28,0x28,0x73,0x69,0x67,0x6e,0x28,0x5f,0x36,0x35,0x31,0x29,0x20, + 0x2a,0x20,0x5f,0x36,0x35,0x31,0x29,0x20,0x2a,0x20,0x5f,0x36,0x35,0x31,0x29,0x20, + 0x2a,0x20,0x5f,0x36,0x38,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28, + 0x28,0x28,0x73,0x69,0x67,0x6e,0x28,0x5f,0x36,0x37,0x32,0x29,0x20,0x2a,0x20,0x5f, + 0x36,0x35,0x37,0x29,0x20,0x2a,0x20,0x5f,0x36,0x39,0x34,0x29,0x20,0x3e,0x20,0x5f, + 0x37,0x30,0x33,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x73,0x71,0x72,0x74,0x28, + 0x5f,0x36,0x38,0x32,0x20,0x2b,0x20,0x5f,0x36,0x39,0x34,0x29,0x20,0x2a,0x20,0x5f, + 0x36,0x36,0x30,0x29,0x20,0x2d,0x20,0x72,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d, + 0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x28,0x73,0x69,0x67,0x6e,0x28, + 0x5f,0x36,0x36,0x38,0x29,0x20,0x2a,0x20,0x5f,0x36,0x35,0x37,0x29,0x20,0x2a,0x20, + 0x5f,0x36,0x38,0x38,0x29,0x20,0x3c,0x20,0x5f,0x37,0x30,0x33,0x29,0x0a,0x20,0x20, + 0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x28,0x73,0x71,0x72,0x74,0x28,0x5f,0x36,0x38,0x32,0x20,0x2b,0x20, + 0x5f,0x36,0x38,0x38,0x29,0x20,0x2a,0x20,0x5f,0x36,0x36,0x30,0x29,0x20,0x2d,0x20, + 0x72,0x31,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65, + 0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x73,0x71,0x72,0x74,0x28,0x28,0x5f,0x36,0x38, + 0x32,0x20,0x2a,0x20,0x5f,0x36,0x35,0x37,0x29,0x20,0x2a,0x20,0x5f,0x36,0x36,0x30, + 0x29,0x20,0x2b,0x20,0x28,0x5f,0x36,0x36,0x38,0x20,0x2a,0x20,0x5f,0x36,0x35,0x31, + 0x29,0x29,0x20,0x2a,0x20,0x5f,0x36,0x36,0x30,0x29,0x20,0x2d,0x20,0x72,0x31,0x3b, + 0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x64,0x52,0x6f,0x75,0x6e, + 0x64,0x43,0x6f,0x6e,0x65,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x2c,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x72,0x31,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x32, + 0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x68,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x35,0x38,0x37,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x32,0x28,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x70,0x2e,0x78,0x7a,0x29,0x2c,0x20, + 0x70,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x35,0x39,0x33,0x20,0x3d,0x20,0x28,0x72,0x31,0x20,0x2d,0x20,0x72,0x32,0x29, + 0x20,0x2f,0x20,0x68,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x35,0x39,0x39,0x20,0x3d,0x20,0x73,0x71,0x72,0x74,0x28,0x31,0x2e,0x30,0x20, + 0x2d,0x20,0x28,0x5f,0x35,0x39,0x33,0x20,0x2a,0x20,0x5f,0x35,0x39,0x33,0x29,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x36,0x30,0x36, + 0x20,0x3d,0x20,0x64,0x6f,0x74,0x28,0x5f,0x35,0x38,0x37,0x2c,0x20,0x76,0x65,0x63, + 0x32,0x28,0x2d,0x5f,0x35,0x39,0x33,0x2c,0x20,0x5f,0x35,0x39,0x39,0x29,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x36,0x30,0x36,0x20,0x3c,0x20, + 0x30,0x2e,0x30,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68, + 0x28,0x5f,0x35,0x38,0x37,0x29,0x20,0x2d,0x20,0x72,0x31,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x36,0x30,0x36,0x20, + 0x3e,0x20,0x28,0x5f,0x35,0x39,0x39,0x20,0x2a,0x20,0x68,0x29,0x29,0x0a,0x20,0x20, + 0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,0x28,0x5f,0x35,0x38,0x37,0x20,0x2d, + 0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x30,0x2c,0x20,0x68,0x29,0x29,0x20,0x2d, + 0x20,0x72,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72, + 0x65,0x74,0x75,0x72,0x6e,0x20,0x64,0x6f,0x74,0x28,0x5f,0x35,0x38,0x37,0x2c,0x20, + 0x76,0x65,0x63,0x32,0x28,0x5f,0x35,0x39,0x39,0x2c,0x20,0x5f,0x35,0x39,0x33,0x29, + 0x29,0x20,0x2d,0x20,0x72,0x31,0x3b,0x0a,0x7d,0x0a,0x0a,0x76,0x65,0x63,0x32,0x20, + 0x6d,0x61,0x70,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x6f,0x73,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x32,0x28,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x2e, + 0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20, + 0x76,0x65,0x63,0x33,0x28,0x2d,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c, + 0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x20,0x3d,0x20,0x30,0x2e,0x32,0x35,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x32,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x20,0x3d,0x20,0x76,0x65,0x63,0x32, + 0x28,0x73,0x64,0x53,0x70,0x68,0x65,0x72,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x29,0x2c,0x20,0x32,0x36,0x2e,0x38,0x39, + 0x39,0x39,0x39,0x39,0x36,0x31,0x38,0x35,0x33,0x30,0x32,0x37,0x33,0x34,0x33,0x37, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70, + 0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x33,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x34,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30, + 0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31, + 0x32,0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x20,0x3d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33, + 0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37,0x35,0x2c,0x20, + 0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32, + 0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x32,0x2e,0x35,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x73,0x64,0x42,0x6f,0x78,0x28, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35, + 0x29,0x20,0x3c,0x20,0x72,0x65,0x73,0x2e,0x78,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x36,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c,0x20,0x30,0x2e, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28, + 0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32, + 0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32,0x35, + 0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30, + 0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x38,0x20,0x3d,0x20,0x30,0x2e,0x30,0x32,0x35,0x30,0x30, + 0x30,0x30,0x30,0x30,0x33,0x37,0x32,0x35,0x32,0x39,0x30,0x32,0x39,0x38,0x34,0x36, + 0x31,0x39,0x31,0x34,0x30,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x36,0x32,0x38,0x20,0x3d,0x20, + 0x73,0x64,0x42,0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x42,0x6f,0x78,0x28,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x36,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x20,0x3d, + 0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x20,0x3d,0x20,0x76,0x65, + 0x63,0x32,0x28,0x5f,0x31,0x36,0x32,0x38,0x2c,0x20,0x31,0x36,0x2e,0x38,0x39,0x39, + 0x39,0x39,0x39,0x36,0x31,0x38,0x35,0x33,0x30,0x32,0x37,0x33,0x34,0x33,0x37,0x35, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d, + 0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x2c,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x31,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x20,0x3d, + 0x20,0x28,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30, + 0x2c,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30, + 0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x31,0x2e, + 0x30,0x29,0x29,0x2e,0x78,0x7a,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x32,0x20,0x3d, + 0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x35, + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34,0x35,0x30,0x35,0x38,0x30,0x35,0x39, + 0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x34,0x20, + 0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x54,0x6f,0x72,0x75,0x73,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31, + 0x32,0x29,0x2c,0x20,0x32,0x35,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x34,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x31,0x35,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20, + 0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x34,0x34,0x39,0x39, + 0x39,0x39,0x39,0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39,0x32, + 0x31,0x38,0x37,0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x36,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x36,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39,0x31,0x30,0x31,0x35, + 0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31, + 0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x37,0x20,0x3d,0x20,0x30,0x2e,0x34,0x34,0x39, + 0x39,0x39,0x39,0x39,0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39, + 0x32,0x31,0x38,0x37,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x38,0x20,0x3d,0x20,0x72, + 0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x39,0x20,0x3d,0x20,0x76,0x65,0x63,0x32, + 0x28,0x73,0x64,0x43,0x6f,0x6e,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x35, + 0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x36,0x2c,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x37,0x29,0x2c,0x20,0x35,0x35,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x38,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x39,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x30,0x20,0x3d,0x20,0x70,0x6f,0x73, + 0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32, + 0x35,0x2c,0x20,0x2d,0x32,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x31, + 0x20,0x3d,0x20,0x30,0x2e,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x32,0x20, + 0x3d,0x20,0x30,0x2e,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x33,0x20,0x3d, + 0x20,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31, + 0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x32,0x34,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x32,0x35,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x43,0x61,0x70,0x70, + 0x65,0x64,0x43,0x6f,0x6e,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x30,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x32,0x32,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x33,0x29,0x2c,0x20, + 0x31,0x33,0x2e,0x36,0x37,0x30,0x30,0x30,0x30,0x30,0x37,0x36,0x32,0x39,0x33,0x39, + 0x34,0x35,0x33,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x32,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x35,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x32,0x36,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x2d,0x33,0x2e, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x37,0x20,0x3d,0x20,0x76,0x65,0x63,0x32, + 0x28,0x30,0x2e,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38, + 0x35,0x37,0x39,0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x38,0x30, + 0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35, + 0x30,0x37,0x38,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x38,0x20, + 0x3d,0x20,0x30,0x2e,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30, + 0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x32,0x39,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33, + 0x30,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x53,0x6f,0x6c,0x69,0x64, + 0x41,0x6e,0x67,0x6c,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x36,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x32,0x38,0x29,0x2c,0x20,0x34,0x39,0x2e,0x31,0x33,0x30,0x30,0x30,0x31,0x30,0x36, + 0x38,0x31,0x31,0x35,0x32,0x33,0x34,0x33,0x37,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x32,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x31,0x20,0x3d,0x20,0x70,0x6f, + 0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e, + 0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39, + 0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x33,0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x33,0x34,0x39,0x39, + 0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36, + 0x30,0x39,0x33,0x37,0x35,0x2c,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30, + 0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32, + 0x35,0x2c,0x20,0x32,0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20, + 0x28,0x73,0x64,0x42,0x6f,0x78,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x31,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x32,0x29,0x20,0x3c,0x20,0x72,0x65,0x73, + 0x2e,0x78,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x33,0x20, + 0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x31,0x2e, + 0x30,0x2c,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32, + 0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x31, + 0x2e,0x30,0x29,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x33,0x28,0x31,0x2e,0x30,0x2c, + 0x20,0x2d,0x31,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x33,0x34,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x38,0x36,0x36,0x30, + 0x32,0x34,0x39,0x37,0x31,0x30,0x30,0x38,0x33,0x30,0x30,0x37,0x38,0x31,0x32,0x35, + 0x2c,0x20,0x2d,0x30,0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x35,0x20, + 0x3d,0x20,0x30,0x2e,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x36,0x20,0x3d, + 0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34,0x35,0x30, + 0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x31,0x37,0x32,0x30,0x20,0x3d,0x20,0x73,0x64,0x43,0x61,0x70,0x70,0x65,0x64,0x54, + 0x6f,0x72,0x75,0x73,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x33,0x2c,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x33,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33, + 0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x36,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x33,0x37,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x38, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x37,0x32,0x30,0x2c,0x20,0x38, + 0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73, + 0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x37,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x38,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33, + 0x39,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x31, + 0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x34,0x30,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x33, + 0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35, + 0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c,0x20,0x30, + 0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31,0x31,0x36, + 0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x34,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34, + 0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x42,0x6f,0x78,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x33,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34, + 0x30,0x29,0x2c,0x20,0x33,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x34,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x32,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x34,0x33,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76, + 0x65,0x63,0x33,0x28,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x2d,0x31, + 0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x34,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x33,0x28,0x2d,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39, + 0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35, + 0x2c,0x20,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30, + 0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x2c, + 0x20,0x2d,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30, + 0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x34,0x35,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30, + 0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32, + 0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x34, + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37, + 0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30, + 0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36, + 0x39,0x35,0x33,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x36,0x20, + 0x3d,0x20,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30, + 0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x34,0x37,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x34,0x38,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x43,0x61,0x70, + 0x73,0x75,0x6c,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x33,0x2c,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x34,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34, + 0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x36,0x29,0x2c,0x20,0x33,0x31, + 0x2e,0x38,0x39,0x39,0x39,0x39,0x39,0x36,0x31,0x38,0x35,0x33,0x30,0x32,0x37,0x33, + 0x34,0x33,0x37,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72, + 0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34, + 0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x38,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x34,0x39,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33, + 0x28,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c,0x20,0x2d,0x32,0x2e,0x30, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x30,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28, + 0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36, + 0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x35,0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64, + 0x43,0x79,0x6c,0x69,0x6e,0x64,0x65,0x72,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34, + 0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x30,0x29,0x2c,0x20,0x38,0x2e, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20, + 0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x31,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x32,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x33, + 0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x31,0x2e, + 0x30,0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38, + 0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x2c, + 0x20,0x2d,0x33,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x34,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32, + 0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32, + 0x35,0x2c,0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34, + 0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x5f,0x31,0x37,0x37,0x36,0x20,0x3d,0x20,0x73,0x64,0x48,0x65,0x78,0x50, + 0x72,0x69,0x73,0x6d,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x33,0x2c,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x35,0x34,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x35,0x20, + 0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x36,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x32,0x28,0x5f,0x31,0x37,0x37,0x36,0x2c,0x20,0x31,0x38,0x2e,0x33,0x39, + 0x39,0x39,0x39,0x39,0x36,0x31,0x38,0x35,0x33,0x30,0x32,0x37,0x33,0x34,0x33,0x37, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20, + 0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x35,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x36,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x35,0x37,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28, + 0x2d,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39, + 0x34,0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37, + 0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x38,0x20,0x3d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33, + 0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37,0x35,0x2c,0x20, + 0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35,0x33, + 0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37,0x35,0x2c,0x20,0x32,0x2e,0x35, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x73,0x64,0x42,0x6f,0x78, + 0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x35,0x38,0x29,0x20,0x3c,0x20,0x72,0x65,0x73,0x2e,0x78,0x29,0x0a,0x20,0x20, + 0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x39,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20, + 0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x2d,0x31,0x2e,0x30,0x2c,0x20,0x2d,0x30,0x2e, + 0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39, + 0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x2d,0x33,0x2e,0x30,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x36,0x30,0x20,0x3d,0x20,0x31,0x2e,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x38,0x30, + 0x31,0x20,0x3d,0x20,0x73,0x64,0x50,0x79,0x72,0x61,0x6d,0x69,0x64,0x28,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x35,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x30, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x31,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x36,0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x38, + 0x30,0x31,0x2c,0x20,0x31,0x33,0x2e,0x35,0x36,0x30,0x30,0x30,0x30,0x34,0x31,0x39, + 0x36,0x31,0x36,0x36,0x39,0x39,0x32,0x31,0x38,0x37,0x35,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x36,0x32,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x33,0x20,0x3d,0x20,0x70,0x6f,0x73, + 0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x2d,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e, + 0x31,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34, + 0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x2d,0x32,0x2e,0x30,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x34,0x20,0x3d,0x20,0x30,0x2e,0x33,0x34,0x39, + 0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34, + 0x36,0x30,0x39,0x33,0x37,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x38,0x31,0x33,0x20,0x3d,0x20,0x73,0x64, + 0x4f,0x63,0x74,0x61,0x68,0x65,0x64,0x72,0x6f,0x6e,0x28,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x36,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x34,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x36,0x35,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x36,0x36,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x38,0x31,0x33,0x2c, + 0x20,0x32,0x33,0x2e,0x35,0x35,0x39,0x39,0x39,0x39,0x34,0x36,0x35,0x39,0x34,0x32, + 0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x36,0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x36,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x36,0x37,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76, + 0x65,0x63,0x33,0x28,0x2d,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x31,0x35,0x30,0x30, + 0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33, + 0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x36,0x38,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x33,0x30,0x30, + 0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30, + 0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30, + 0x30,0x30,0x37,0x34,0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38, + 0x32,0x38,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x38,0x32,0x36,0x20,0x3d,0x20,0x73,0x64, + 0x54,0x72,0x69,0x50,0x72,0x69,0x73,0x6d,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36, + 0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x38,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x36,0x39,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x30, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x38,0x32,0x36,0x2c,0x20,0x34, + 0x33,0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65, + 0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x36,0x39, + 0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x37,0x31,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28, + 0x2d,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x37,0x32,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30, + 0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32, + 0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32, + 0x35,0x2c,0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34, + 0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x33,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x37,0x34,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64, + 0x45,0x6c,0x6c,0x69,0x70,0x73,0x6f,0x69,0x64,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x37,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x32,0x29,0x2c,0x20,0x34, + 0x33,0x2e,0x31,0x36,0x39,0x39,0x39,0x38,0x31,0x36,0x38,0x39,0x34,0x35,0x33,0x31, + 0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73, + 0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x33,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x34,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37, + 0x35,0x20,0x3d,0x20,0x28,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28, + 0x2d,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x33,0x34,0x30,0x30,0x30,0x30,0x30,0x30, + 0x33,0x35,0x37,0x36,0x32,0x37,0x38,0x36,0x38,0x36,0x35,0x32,0x33,0x34,0x33,0x37, + 0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29,0x2e,0x78,0x7a,0x79,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x37,0x36,0x20,0x3d,0x20,0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30,0x30, + 0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36, + 0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x37,0x20,0x3d,0x20,0x30,0x2e,0x32, + 0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x38,0x20,0x3d,0x20,0x30,0x2e,0x30,0x33, + 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x31,0x30,0x35,0x39,0x33,0x30,0x33,0x32,0x38, + 0x33,0x36,0x39,0x31,0x34,0x30,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37, + 0x39,0x20,0x3d,0x20,0x30,0x2e,0x30,0x37,0x39,0x39,0x39,0x39,0x39,0x39,0x38,0x32, + 0x31,0x31,0x38,0x36,0x30,0x36,0x35,0x36,0x37,0x33,0x38,0x32,0x38,0x31,0x32,0x35, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x31,0x38,0x35,0x38,0x20,0x3d,0x20,0x73,0x64,0x52,0x68,0x6f,0x6d,0x62,0x75, + 0x73,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x35,0x2c,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x37,0x36,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x37,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x38,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x37,0x39,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x30,0x20,0x3d,0x20,0x72,0x65,0x73, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x38,0x31,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f, + 0x31,0x38,0x35,0x38,0x2c,0x20,0x31,0x37,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x38,0x30,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38, + 0x31,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x32,0x20,0x3d,0x20,0x70,0x6f, + 0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e, + 0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39, + 0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x2c,0x20,0x2d,0x31,0x2e,0x30,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x38,0x33,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x33,0x34,0x39,0x39, + 0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36, + 0x30,0x39,0x33,0x37,0x35,0x2c,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30, + 0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32, + 0x35,0x2c,0x20,0x32,0x2e,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20, + 0x28,0x73,0x64,0x42,0x6f,0x78,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x32,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x33,0x29,0x20,0x3c,0x20,0x72,0x65,0x73, + 0x2e,0x78,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x34,0x20, + 0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x32,0x2e,0x30, + 0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30, + 0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x2c,0x20, + 0x2d,0x33,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x35,0x20,0x3d,0x20, + 0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33, + 0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x38,0x36,0x20,0x3d,0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30, + 0x30,0x30,0x37,0x34,0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38, + 0x32,0x38,0x31,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x31,0x38,0x38,0x32,0x20,0x3d,0x20,0x73,0x64,0x4f, + 0x63,0x74,0x6f,0x67,0x6f,0x6e,0x50,0x72,0x69,0x73,0x6d,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x38,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x35,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x36,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x37, + 0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x38,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x32,0x28,0x5f,0x31,0x38,0x38,0x32,0x2c,0x20,0x35,0x31,0x2e,0x37, + 0x39,0x39,0x39,0x39,0x39,0x32,0x33,0x37,0x30,0x36,0x30,0x35,0x34,0x36,0x38,0x37, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20, + 0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x37,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x38,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x39, + 0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x32,0x2e, + 0x30,0x2c,0x20,0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36, + 0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20, + 0x2d,0x32,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x30,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x33,0x28,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34, + 0x39,0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32, + 0x35,0x2c,0x20,0x2d,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34, + 0x39,0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32, + 0x35,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x31,0x20,0x3d, + 0x20,0x76,0x65,0x63,0x33,0x28,0x2d,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30, + 0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33, + 0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39,0x34, + 0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37,0x35, + 0x2c,0x20,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30, + 0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x32,0x20,0x3d,0x20,0x30,0x2e,0x30,0x37,0x39, + 0x39,0x39,0x39,0x39,0x39,0x38,0x32,0x31,0x31,0x38,0x36,0x30,0x36,0x35,0x36,0x37, + 0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x33,0x20,0x3d, + 0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x34,0x20,0x3d,0x20,0x76,0x65, + 0x63,0x32,0x28,0x73,0x64,0x43,0x79,0x6c,0x69,0x6e,0x64,0x65,0x72,0x28,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x38,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x30, + 0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x31,0x2c,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x39,0x32,0x29,0x2c,0x20,0x33,0x31,0x2e,0x32,0x30,0x30,0x30,0x30,0x30, + 0x37,0x36,0x32,0x39,0x33,0x39,0x34,0x35,0x33,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55, + 0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x39,0x34,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x35,0x20,0x3d,0x20,0x70,0x6f, + 0x73,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31,0x31,0x36,0x31, + 0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x2c,0x20,0x2d,0x31,0x2e, + 0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x36,0x20,0x3d,0x20,0x76,0x65,0x63,0x33, + 0x28,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31, + 0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x2c,0x20, + 0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x37, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x2d,0x30,0x2e,0x32,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39, + 0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x34,0x30,0x30,0x30,0x30,0x30,0x30, + 0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36, + 0x32,0x35,0x2c,0x20,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34, + 0x39,0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x38,0x20,0x3d,0x20,0x30,0x2e,0x31, + 0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37, + 0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x39, + 0x20,0x3d,0x20,0x30,0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34, + 0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32, + 0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x30,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x31,0x30,0x31,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73, + 0x64,0x43,0x61,0x70,0x70,0x65,0x64,0x43,0x6f,0x6e,0x65,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x39,0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x36,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x39,0x38,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x39,0x29,0x2c,0x20,0x34, + 0x36,0x2e,0x30,0x39,0x39,0x39,0x39,0x38,0x34,0x37,0x34,0x31,0x32,0x31,0x30,0x39, + 0x33,0x37,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65, + 0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30, + 0x30,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x31,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x30,0x32,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76,0x65, + 0x63,0x33,0x28,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30, + 0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30, + 0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30, + 0x33,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x31,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34, + 0x37,0x36,0x35,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x34,0x20,0x3d,0x20,0x76,0x65,0x63,0x33, + 0x28,0x2d,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30, + 0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x2c, + 0x20,0x30,0x2e,0x33,0x34,0x39,0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35, + 0x33,0x35,0x35,0x32,0x32,0x34,0x36,0x30,0x39,0x33,0x37,0x35,0x2c,0x20,0x30,0x2e, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31,0x31,0x36,0x31, + 0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x30,0x35,0x20,0x3d,0x20,0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30, + 0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30, + 0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x36,0x20,0x3d,0x20,0x30, + 0x2e,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x37,0x34,0x35,0x30,0x35,0x38, + 0x30,0x35,0x39,0x36,0x39,0x32,0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x30,0x37,0x20,0x3d,0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x30,0x38,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x73,0x64,0x52,0x6f,0x75, + 0x6e,0x64,0x43,0x6f,0x6e,0x65,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x32, + 0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x33,0x2c,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x30,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30, + 0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x36,0x29,0x2c,0x20,0x35, + 0x31,0x2e,0x37,0x30,0x30,0x30,0x30,0x30,0x37,0x36,0x32,0x39,0x33,0x39,0x34,0x35, + 0x33,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72, + 0x65,0x73,0x20,0x3d,0x20,0x6f,0x70,0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31, + 0x30,0x37,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x38,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x30,0x39,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2d,0x20,0x76, + 0x65,0x63,0x33,0x28,0x32,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39, + 0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x31,0x31,0x30,0x20,0x3d,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30, + 0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33, + 0x31,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x31,0x20,0x3d,0x20,0x30, + 0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x34,0x39,0x30,0x31,0x31,0x36, + 0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x31,0x32,0x20,0x3d,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30, + 0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31, + 0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x33,0x20,0x3d,0x20,0x72,0x65,0x73, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x34,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28, + 0x73,0x64,0x52,0x6f,0x75,0x6e,0x64,0x43,0x6f,0x6e,0x65,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x30,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x30, + 0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x31,0x2c,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x31,0x32,0x29,0x2c,0x20,0x33,0x37,0x2e,0x30,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x6f,0x70, + 0x55,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x33,0x2c,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x31,0x34,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65,0x73,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x76,0x65,0x63,0x32,0x20,0x72,0x61,0x79,0x63,0x61,0x73,0x74,0x28,0x76, + 0x65,0x63,0x33,0x20,0x72,0x6f,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72,0x64,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x72,0x65,0x73,0x20, + 0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x2d,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x74,0x6d,0x69,0x6e,0x20,0x3d,0x20,0x31, + 0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x74,0x6d, + 0x61,0x78,0x20,0x3d,0x20,0x32,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x30,0x30,0x39,0x20,0x3d,0x20,0x28,0x2d,0x72, + 0x6f,0x2e,0x79,0x29,0x20,0x2f,0x20,0x72,0x64,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x69,0x66,0x20,0x28,0x5f,0x32,0x30,0x30,0x39,0x20,0x3e,0x20,0x30,0x2e,0x30, + 0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x74,0x6d,0x61,0x78,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x74,0x6d,0x61,0x78,0x2c, + 0x20,0x5f,0x32,0x30,0x30,0x39,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x5f,0x32,0x30,0x30, + 0x39,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20, + 0x72,0x6f,0x20,0x2d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x2c,0x20,0x30, + 0x2e,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34, + 0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x35, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x31,0x20,0x3d,0x20,0x72,0x64,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x33,0x28,0x32,0x2e,0x35,0x2c,0x20,0x30,0x2e,0x34,0x30,0x39,0x39,0x39,0x39,0x39, + 0x39,0x36,0x34,0x32,0x33,0x37,0x32,0x31,0x33,0x31,0x33,0x34,0x37,0x36,0x35,0x36, + 0x32,0x35,0x2c,0x20,0x33,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x32,0x20,0x5f,0x32,0x30,0x32,0x39,0x20,0x3d,0x20,0x69,0x42,0x6f,0x78,0x28, + 0x70,0x61,0x72,0x61,0x6d,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x2c,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x5f,0x32,0x30,0x33,0x31,0x20,0x3d,0x20,0x5f,0x32,0x30,0x32, + 0x39,0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x32,0x30,0x33,0x33,0x20,0x3d,0x20,0x5f,0x32,0x30,0x32,0x39,0x2e,0x79,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x32,0x30,0x33,0x34,0x20,0x3d, + 0x20,0x5f,0x32,0x30,0x33,0x31,0x20,0x3c,0x20,0x5f,0x32,0x30,0x33,0x33,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x32,0x30,0x34,0x30,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x32,0x30,0x33,0x34,0x29,0x0a,0x20, + 0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x32,0x30, + 0x34,0x30,0x20,0x3d,0x20,0x5f,0x32,0x30,0x33,0x33,0x20,0x3e,0x20,0x30,0x2e,0x30, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x65,0x6c,0x73,0x65, + 0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f, + 0x32,0x30,0x34,0x30,0x20,0x3d,0x20,0x5f,0x32,0x30,0x33,0x34,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x32,0x30, + 0x34,0x37,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x32,0x30,0x34, + 0x30,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x5f,0x32,0x30,0x34,0x37,0x20,0x3d,0x20,0x5f,0x32,0x30,0x33,0x31,0x20,0x3c, + 0x20,0x74,0x6d,0x61,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20, + 0x20,0x65,0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x5f,0x32,0x30,0x34,0x37,0x20,0x3d,0x20,0x5f,0x32,0x30,0x34, + 0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20, + 0x28,0x5f,0x32,0x30,0x34,0x37,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x30,0x35, + 0x32,0x20,0x3d,0x20,0x74,0x6d,0x69,0x6e,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x30,0x35,0x33,0x20,0x3d,0x20, + 0x6d,0x61,0x78,0x28,0x5f,0x32,0x30,0x33,0x31,0x2c,0x20,0x5f,0x32,0x30,0x35,0x32, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x6d,0x69,0x6e,0x20, + 0x3d,0x20,0x5f,0x32,0x30,0x35,0x33,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x74,0x6d,0x61,0x78,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x5f,0x32,0x30,0x33, + 0x33,0x2c,0x20,0x74,0x6d,0x61,0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x74,0x20,0x3d,0x20,0x5f,0x32,0x30,0x35, + 0x33,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28, + 0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x30,0x3b,0x20,0x28,0x69,0x20,0x3c,0x20, + 0x37,0x30,0x29,0x20,0x26,0x26,0x20,0x28,0x74,0x20,0x3c,0x20,0x74,0x6d,0x61,0x78, + 0x29,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x20,0x3d,0x20,0x72,0x6f,0x20, + 0x2b,0x20,0x28,0x72,0x64,0x20,0x2a,0x20,0x74,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x30, + 0x38,0x33,0x20,0x3d,0x20,0x6d,0x61,0x70,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33, + 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x30,0x38,0x35,0x20,0x3d,0x20,0x5f,0x32,0x30, + 0x38,0x33,0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x69,0x66,0x20,0x28,0x61,0x62,0x73,0x28,0x5f,0x32,0x30,0x38,0x35,0x29, + 0x20,0x3c,0x20,0x28,0x39,0x2e,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x34,0x37,0x33, + 0x37,0x38,0x37,0x35,0x31,0x36,0x33,0x35,0x35,0x35,0x31,0x34,0x35,0x32,0x36,0x33, + 0x36,0x37,0x31,0x38,0x38,0x65,0x2d,0x30,0x35,0x20,0x2a,0x20,0x74,0x29,0x29,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65, + 0x73,0x20,0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x74,0x2c,0x20,0x5f,0x32,0x30,0x38, + 0x33,0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x20,0x2b,0x3d,0x20,0x5f,0x32,0x30,0x38, + 0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x65, + 0x73,0x3b,0x0a,0x7d,0x0a,0x0a,0x76,0x65,0x63,0x33,0x20,0x63,0x61,0x6c,0x63,0x4e, + 0x6f,0x72,0x6d,0x61,0x6c,0x28,0x76,0x65,0x63,0x33,0x20,0x70,0x6f,0x73,0x29,0x0a, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x6e,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6f, + 0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x69, + 0x6e,0x74,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2e, + 0x79,0x29,0x2c,0x20,0x30,0x29,0x3b,0x20,0x69,0x20,0x3c,0x20,0x34,0x3b,0x20,0x69, + 0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x32,0x32,0x31,0x20,0x3d,0x20,0x28, + 0x28,0x76,0x65,0x63,0x33,0x28,0x66,0x6c,0x6f,0x61,0x74,0x28,0x28,0x28,0x69,0x20, + 0x2b,0x20,0x33,0x29,0x20,0x3e,0x3e,0x20,0x31,0x29,0x20,0x26,0x20,0x31,0x29,0x2c, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x28,0x28,0x69,0x20,0x3e,0x3e,0x20,0x31,0x29,0x20, + 0x26,0x20,0x31,0x29,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x28,0x69,0x20,0x26,0x20, + 0x31,0x29,0x29,0x20,0x2a,0x20,0x32,0x2e,0x30,0x29,0x20,0x2d,0x20,0x76,0x65,0x63, + 0x33,0x28,0x31,0x2e,0x30,0x29,0x29,0x20,0x2a,0x20,0x30,0x2e,0x35,0x37,0x37,0x33, + 0x30,0x30,0x30,0x31,0x32,0x31,0x31,0x31,0x36,0x36,0x33,0x38,0x31,0x38,0x33,0x35, + 0x39,0x33,0x37,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65, + 0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2b, + 0x20,0x28,0x5f,0x32,0x32,0x32,0x31,0x20,0x2a,0x20,0x30,0x2e,0x30,0x30,0x30,0x35, + 0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x33,0x37,0x34,0x38,0x37,0x32,0x35,0x36,0x35, + 0x32,0x36,0x39,0x34,0x37,0x30,0x32,0x31,0x34,0x38,0x34,0x33,0x37,0x35,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6e,0x20,0x2b,0x3d,0x20,0x28,0x5f, + 0x32,0x32,0x32,0x31,0x20,0x2a,0x20,0x6d,0x61,0x70,0x28,0x70,0x61,0x72,0x61,0x6d, + 0x29,0x2e,0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20, + 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65, + 0x28,0x6e,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x63,0x68, + 0x65,0x63,0x6b,0x65,0x72,0x73,0x47,0x72,0x61,0x64,0x42,0x6f,0x78,0x28,0x76,0x65, + 0x63,0x32,0x20,0x70,0x2c,0x20,0x76,0x65,0x63,0x32,0x20,0x64,0x70,0x64,0x78,0x2c, + 0x20,0x76,0x65,0x63,0x32,0x20,0x64,0x70,0x64,0x79,0x29,0x0a,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x33,0x30,0x39,0x20,0x3d,0x20,0x28, + 0x61,0x62,0x73,0x28,0x64,0x70,0x64,0x78,0x29,0x20,0x2b,0x20,0x61,0x62,0x73,0x28, + 0x64,0x70,0x64,0x79,0x29,0x29,0x20,0x2b,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e, + 0x30,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x37,0x34,0x39,0x37,0x34, + 0x35,0x31,0x33,0x30,0x35,0x33,0x38,0x39,0x34,0x30,0x34,0x32,0x39,0x36,0x38,0x37, + 0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x33, + 0x31,0x33,0x20,0x3d,0x20,0x5f,0x32,0x33,0x30,0x39,0x20,0x2a,0x20,0x30,0x2e,0x35, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x33,0x33,0x32, + 0x20,0x3d,0x20,0x28,0x28,0x61,0x62,0x73,0x28,0x66,0x72,0x61,0x63,0x74,0x28,0x28, + 0x70,0x20,0x2d,0x20,0x5f,0x32,0x33,0x31,0x33,0x29,0x20,0x2a,0x20,0x30,0x2e,0x35, + 0x29,0x20,0x2d,0x20,0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x35,0x29,0x29,0x20,0x2d, + 0x20,0x61,0x62,0x73,0x28,0x66,0x72,0x61,0x63,0x74,0x28,0x28,0x70,0x20,0x2b,0x20, + 0x5f,0x32,0x33,0x31,0x33,0x29,0x20,0x2a,0x20,0x30,0x2e,0x35,0x29,0x20,0x2d,0x20, + 0x76,0x65,0x63,0x32,0x28,0x30,0x2e,0x35,0x29,0x29,0x29,0x20,0x2a,0x20,0x32,0x2e, + 0x30,0x29,0x20,0x2f,0x20,0x5f,0x32,0x33,0x30,0x39,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x2e,0x35,0x20,0x2d,0x20,0x28,0x28,0x30, + 0x2e,0x35,0x20,0x2a,0x20,0x5f,0x32,0x33,0x33,0x32,0x2e,0x78,0x29,0x20,0x2a,0x20, + 0x5f,0x32,0x33,0x33,0x32,0x2e,0x79,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x63,0x61,0x6c,0x63,0x41,0x4f,0x28,0x76,0x65,0x63,0x33,0x20,0x70, + 0x6f,0x73,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x6e,0x6f,0x72,0x29,0x0a,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6f,0x63,0x63,0x20,0x3d,0x20, + 0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73, + 0x63,0x61,0x20,0x3d,0x20,0x31,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6f, + 0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28,0x69, + 0x6e,0x74,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2e, + 0x79,0x29,0x2c,0x20,0x30,0x29,0x3b,0x20,0x69,0x20,0x3c,0x20,0x35,0x3b,0x20,0x69, + 0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x32,0x36,0x33,0x20,0x3d,0x20, + 0x30,0x2e,0x30,0x30,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x37,0x36,0x34,0x38, + 0x32,0x35,0x38,0x32,0x30,0x39,0x32,0x32,0x38,0x35,0x31,0x35,0x36,0x32,0x35,0x20, + 0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x28,0x69,0x29,0x20,0x2a,0x20,0x30,0x2e, + 0x30,0x32,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x33,0x32,0x39,0x34,0x34,0x37,0x37, + 0x34,0x36,0x32,0x37,0x36,0x38,0x35,0x35,0x34,0x36,0x38,0x37,0x35,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x20,0x3d,0x20,0x70,0x6f,0x73,0x20,0x2b,0x20,0x28,0x6e,0x6f,0x72,0x20, + 0x2a,0x20,0x5f,0x32,0x32,0x36,0x33,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x32,0x37,0x36,0x20,0x3d,0x20, + 0x73,0x63,0x61,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x32,0x32,0x37,0x38,0x20,0x3d,0x20,0x6f,0x63,0x63,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32, + 0x32,0x37,0x39,0x20,0x3d,0x20,0x5f,0x32,0x32,0x37,0x38,0x20,0x2b,0x20,0x28,0x28, + 0x5f,0x32,0x32,0x36,0x33,0x20,0x2d,0x20,0x6d,0x61,0x70,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x29,0x2e,0x78,0x29,0x20,0x2a,0x20,0x5f,0x32,0x32,0x37,0x36,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x63,0x63,0x20,0x3d,0x20,0x5f,0x32, + 0x32,0x37,0x39,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x63,0x61, + 0x20,0x3d,0x20,0x5f,0x32,0x32,0x37,0x36,0x20,0x2a,0x20,0x30,0x2e,0x39,0x34,0x39, + 0x39,0x39,0x39,0x39,0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39, + 0x32,0x31,0x38,0x37,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, + 0x66,0x20,0x28,0x5f,0x32,0x32,0x37,0x39,0x20,0x3e,0x20,0x30,0x2e,0x33,0x34,0x39, + 0x39,0x39,0x39,0x39,0x39,0x34,0x30,0x33,0x39,0x35,0x33,0x35,0x35,0x32,0x32,0x34, + 0x36,0x30,0x39,0x33,0x37,0x35,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x72, + 0x65,0x61,0x6b,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20, + 0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, + 0x63,0x6c,0x61,0x6d,0x70,0x28,0x31,0x2e,0x30,0x20,0x2d,0x20,0x28,0x33,0x2e,0x30, + 0x20,0x2a,0x20,0x6f,0x63,0x63,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e, + 0x30,0x29,0x20,0x2a,0x20,0x28,0x30,0x2e,0x35,0x20,0x2b,0x20,0x28,0x30,0x2e,0x35, + 0x20,0x2a,0x20,0x6e,0x6f,0x72,0x2e,0x79,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x63,0x61,0x6c,0x63,0x53,0x6f,0x66,0x74,0x73,0x68,0x61, + 0x64,0x6f,0x77,0x28,0x76,0x65,0x63,0x33,0x20,0x72,0x6f,0x2c,0x20,0x76,0x65,0x63, + 0x33,0x20,0x72,0x64,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6d,0x69,0x6e,0x74, + 0x2c,0x20,0x69,0x6e,0x6f,0x75,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x74,0x6d, + 0x61,0x78,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x32,0x31,0x31,0x34,0x20,0x3d,0x20,0x28,0x30,0x2e,0x38,0x30,0x30,0x30,0x30, + 0x30,0x30,0x31,0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38, + 0x31,0x32,0x35,0x20,0x2d,0x20,0x72,0x6f,0x2e,0x79,0x29,0x20,0x2f,0x20,0x72,0x64, + 0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x5f,0x32,0x31,0x31, + 0x34,0x20,0x3e,0x20,0x30,0x2e,0x30,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x6d,0x61,0x78,0x20,0x3d,0x20,0x6d,0x69, + 0x6e,0x28,0x74,0x6d,0x61,0x78,0x2c,0x20,0x5f,0x32,0x31,0x31,0x34,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x65,0x73,0x20,0x3d,0x20,0x31,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x74,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x74,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x20,0x3d,0x20, + 0x6d,0x69,0x6e,0x28,0x69,0x6e,0x74,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d, + 0x73,0x5b,0x31,0x5d,0x2e,0x79,0x29,0x2c,0x20,0x30,0x29,0x3b,0x20,0x69,0x20,0x3c, + 0x20,0x32,0x34,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x20,0x3d,0x20,0x72,0x6f,0x20,0x2b,0x20,0x28,0x72,0x64,0x20,0x2a,0x20, + 0x74,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32, + 0x20,0x5f,0x32,0x31,0x35,0x30,0x20,0x3d,0x20,0x6d,0x61,0x70,0x28,0x70,0x61,0x72, + 0x61,0x6d,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x32,0x31,0x35,0x31,0x20,0x3d,0x20,0x5f,0x32,0x31,0x35,0x30, + 0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x5f,0x32,0x31,0x35,0x35,0x20,0x3d,0x20,0x74,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x31,0x35,0x37, + 0x20,0x3d,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x28,0x38,0x2e,0x30,0x20,0x2a,0x20, + 0x5f,0x32,0x31,0x35,0x31,0x29,0x20,0x2f,0x20,0x5f,0x32,0x31,0x35,0x35,0x2c,0x20, + 0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x31,0x35,0x38,0x20,0x3d, + 0x20,0x72,0x65,0x73,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x5f,0x32,0x31,0x36,0x36,0x20,0x3d,0x20,0x6d,0x69,0x6e,0x28, + 0x5f,0x32,0x31,0x35,0x38,0x2c,0x20,0x28,0x5f,0x32,0x31,0x35,0x37,0x20,0x2a,0x20, + 0x5f,0x32,0x31,0x35,0x37,0x29,0x20,0x2a,0x20,0x28,0x33,0x2e,0x30,0x20,0x2d,0x20, + 0x28,0x32,0x2e,0x30,0x20,0x2a,0x20,0x5f,0x32,0x31,0x35,0x37,0x29,0x29,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x20,0x3d,0x20,0x5f, + 0x32,0x31,0x36,0x36,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x5f,0x32,0x31,0x37,0x31,0x20,0x3d,0x20,0x5f,0x32,0x31,0x35, + 0x35,0x20,0x2b,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x5f,0x32,0x31,0x35,0x31,0x2c, + 0x20,0x30,0x2e,0x30,0x31,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x35,0x35,0x32,0x39, + 0x36,0x35,0x31,0x36,0x34,0x31,0x38,0x34,0x35,0x37,0x30,0x33,0x31,0x32,0x35,0x2c, + 0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32, + 0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x20,0x3d,0x20,0x5f,0x32,0x31,0x37, + 0x31,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66,0x20,0x28,0x28, + 0x5f,0x32,0x31,0x36,0x36,0x20,0x3c,0x20,0x30,0x2e,0x30,0x30,0x34,0x30,0x30,0x30, + 0x30,0x30,0x30,0x31,0x38,0x39,0x39,0x38,0x39,0x38,0x30,0x35,0x32,0x32,0x31,0x35, + 0x35,0x37,0x36,0x31,0x37,0x31,0x38,0x37,0x35,0x29,0x20,0x7c,0x7c,0x20,0x28,0x5f, + 0x32,0x31,0x37,0x31,0x20,0x3e,0x20,0x74,0x6d,0x61,0x78,0x29,0x29,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x62,0x72,0x65,0x61,0x6b,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x72, + 0x65,0x74,0x75,0x72,0x6e,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x72,0x65,0x73,0x2c, + 0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x76, + 0x65,0x63,0x33,0x20,0x72,0x65,0x6e,0x64,0x65,0x72,0x28,0x76,0x65,0x63,0x33,0x20, + 0x72,0x6f,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72,0x64,0x2c,0x20,0x76,0x65,0x63, + 0x33,0x20,0x72,0x64,0x78,0x2c,0x20,0x76,0x65,0x63,0x33,0x20,0x72,0x64,0x79,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x63,0x6f,0x6c,0x20, + 0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x36,0x39,0x39,0x39,0x39,0x39,0x39, + 0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39,0x32,0x31,0x38,0x37, + 0x35,0x2c,0x20,0x30,0x2e,0x36,0x39,0x39,0x39,0x39,0x39,0x39,0x38,0x38,0x30,0x37, + 0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39,0x32,0x31,0x38,0x37,0x35,0x2c,0x20,0x30, + 0x2e,0x38,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x36,0x31,0x35,0x38,0x31,0x34,0x32, + 0x30,0x38,0x39,0x38,0x34,0x33,0x37,0x35,0x29,0x20,0x2d,0x20,0x76,0x65,0x63,0x33, + 0x28,0x6d,0x61,0x78,0x28,0x72,0x64,0x2e,0x79,0x2c,0x20,0x30,0x2e,0x30,0x29,0x20, + 0x2a,0x20,0x30,0x2e,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x39,0x32,0x30, + 0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20, + 0x72,0x6f,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72, + 0x61,0x6d,0x5f,0x31,0x20,0x3d,0x20,0x72,0x64,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x5f,0x32,0x33,0x35,0x37,0x20,0x3d,0x20,0x72,0x61,0x79,0x63, + 0x61,0x73,0x74,0x28,0x70,0x61,0x72,0x61,0x6d,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x31,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x32,0x33,0x36,0x30,0x20,0x3d,0x20,0x5f,0x32,0x33,0x35,0x37,0x2e,0x78,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x33,0x36,0x33,0x20, + 0x3d,0x20,0x5f,0x32,0x33,0x35,0x37,0x2e,0x79,0x3b,0x0a,0x20,0x20,0x20,0x20,0x69, + 0x66,0x20,0x28,0x5f,0x32,0x33,0x36,0x33,0x20,0x3e,0x20,0x28,0x2d,0x30,0x2e,0x35, + 0x29,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x33,0x37,0x33,0x20,0x3d,0x20,0x72,0x6f, + 0x20,0x2b,0x20,0x28,0x72,0x64,0x20,0x2a,0x20,0x5f,0x32,0x33,0x36,0x30,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x6f,0x6f,0x6c,0x20,0x5f,0x32, + 0x33,0x37,0x37,0x20,0x3d,0x20,0x5f,0x32,0x33,0x36,0x33,0x20,0x3c,0x20,0x31,0x2e, + 0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20, + 0x5f,0x32,0x33,0x37,0x38,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, + 0x66,0x20,0x28,0x5f,0x32,0x33,0x37,0x37,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x5f,0x32,0x33,0x37,0x38,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30, + 0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x65, + 0x6c,0x73,0x65,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x32,0x20,0x3d,0x20,0x5f,0x32,0x33,0x37,0x33,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x5f,0x32,0x33,0x37, + 0x38,0x20,0x3d,0x20,0x63,0x61,0x6c,0x63,0x4e,0x6f,0x72,0x6d,0x61,0x6c,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x32,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20, + 0x5f,0x32,0x33,0x39,0x30,0x20,0x3d,0x20,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x28, + 0x72,0x64,0x2c,0x20,0x5f,0x32,0x33,0x37,0x38,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30, + 0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32, + 0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x29,0x20,0x2b,0x20,0x28, + 0x73,0x69,0x6e,0x28,0x76,0x65,0x63,0x33,0x28,0x5f,0x32,0x33,0x36,0x33,0x20,0x2a, + 0x20,0x32,0x2e,0x30,0x29,0x20,0x2b,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30, + 0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20,0x32,0x2e,0x30,0x29,0x29,0x20,0x2a,0x20,0x30, + 0x2e,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32, + 0x32,0x33,0x38,0x37,0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x6b,0x73,0x20,0x3d, + 0x20,0x31,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x66, + 0x20,0x28,0x5f,0x32,0x33,0x37,0x37,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x33,0x20,0x3d,0x20,0x5f,0x32, + 0x33,0x37,0x33,0x2e,0x78,0x7a,0x20,0x2a,0x20,0x33,0x2e,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x34,0x20,0x3d,0x20,0x28,0x28,0x28,0x72,0x64,0x20,0x2f, + 0x20,0x76,0x65,0x63,0x33,0x28,0x72,0x64,0x2e,0x79,0x29,0x29,0x20,0x2d,0x20,0x28, + 0x72,0x64,0x78,0x20,0x2f,0x20,0x76,0x65,0x63,0x33,0x28,0x72,0x64,0x78,0x2e,0x79, + 0x29,0x29,0x29,0x20,0x2a,0x20,0x72,0x6f,0x2e,0x79,0x29,0x2e,0x78,0x7a,0x20,0x2a, + 0x20,0x33,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x20,0x3d, + 0x20,0x28,0x28,0x28,0x72,0x64,0x20,0x2f,0x20,0x76,0x65,0x63,0x33,0x28,0x72,0x64, + 0x2e,0x79,0x29,0x29,0x20,0x2d,0x20,0x28,0x72,0x64,0x79,0x20,0x2f,0x20,0x76,0x65, + 0x63,0x33,0x28,0x72,0x64,0x79,0x2e,0x79,0x29,0x29,0x29,0x20,0x2a,0x20,0x72,0x6f, + 0x2e,0x79,0x29,0x2e,0x78,0x7a,0x20,0x2a,0x20,0x33,0x2e,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x31,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x35, + 0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35, + 0x29,0x20,0x2b,0x20,0x28,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x35,0x30,0x30, + 0x30,0x30,0x30,0x30,0x30,0x37,0x34,0x35,0x30,0x35,0x38,0x30,0x35,0x39,0x36,0x39, + 0x32,0x33,0x38,0x32,0x38,0x31,0x32,0x35,0x29,0x20,0x2a,0x20,0x63,0x68,0x65,0x63, + 0x6b,0x65,0x72,0x73,0x47,0x72,0x61,0x64,0x42,0x6f,0x78,0x28,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x2c,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x35,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x6b,0x73,0x20,0x3d,0x20,0x30,0x2e,0x34,0x30,0x30,0x30, + 0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33, + 0x39,0x30,0x36,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d, + 0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x36,0x20,0x3d,0x20,0x5f,0x32,0x33,0x37,0x33,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x37,0x20,0x3d,0x20,0x5f,0x32,0x33,0x37,0x38,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x34,0x35,0x39, + 0x20,0x3d,0x20,0x63,0x61,0x6c,0x63,0x41,0x4f,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x36,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x37,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x6c,0x69,0x6e,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x34,0x37,0x30,0x20,0x3d,0x20, + 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28,0x76,0x65,0x63,0x33,0x28,0x2d, + 0x30,0x2e,0x35,0x36,0x39,0x38,0x30,0x32,0x38,0x38,0x30,0x32,0x38,0x37,0x31,0x37, + 0x30,0x34,0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x34,0x35,0x35, + 0x38,0x34,0x32,0x33,0x31,0x36,0x31,0x35,0x30,0x36,0x36,0x35,0x32,0x38,0x33,0x32, + 0x30,0x33,0x31,0x32,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x36,0x38,0x33,0x37,0x36,0x33, + 0x34,0x34,0x34,0x34,0x32,0x33,0x36,0x37,0x35,0x35,0x33,0x37,0x31,0x30,0x39,0x33, + 0x37,0x35,0x29,0x20,0x2d,0x20,0x72,0x64,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x64,0x69,0x66,0x20,0x3d,0x20,0x63, + 0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28,0x5f,0x32,0x33,0x37,0x38,0x2c,0x20, + 0x76,0x65,0x63,0x33,0x28,0x2d,0x30,0x2e,0x35,0x36,0x39,0x38,0x30,0x32,0x38,0x38, + 0x30,0x32,0x38,0x37,0x31,0x37,0x30,0x34,0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c, + 0x20,0x30,0x2e,0x34,0x35,0x35,0x38,0x34,0x32,0x33,0x31,0x36,0x31,0x35,0x30,0x36, + 0x36,0x35,0x32,0x38,0x33,0x32,0x30,0x33,0x31,0x32,0x35,0x2c,0x20,0x2d,0x30,0x2e, + 0x36,0x38,0x33,0x37,0x36,0x33,0x34,0x34,0x34,0x34,0x32,0x33,0x36,0x37,0x35,0x35, + 0x33,0x37,0x31,0x30,0x39,0x33,0x37,0x35,0x29,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c, + 0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x20,0x3d,0x20,0x5f,0x32, + 0x33,0x37,0x33,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x39,0x20,0x3d,0x20,0x76,0x65,0x63,0x33, + 0x28,0x2d,0x30,0x2e,0x35,0x36,0x39,0x38,0x30,0x32,0x38,0x38,0x30,0x32,0x38,0x37, + 0x31,0x37,0x30,0x34,0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x34, + 0x35,0x35,0x38,0x34,0x32,0x33,0x31,0x36,0x31,0x35,0x30,0x36,0x36,0x35,0x32,0x38, + 0x33,0x32,0x30,0x33,0x31,0x32,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x36,0x38,0x33,0x37, + 0x36,0x33,0x34,0x34,0x34,0x34,0x32,0x33,0x36,0x37,0x35,0x35,0x33,0x37,0x31,0x30, + 0x39,0x33,0x37,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x20,0x3d,0x20, + 0x30,0x2e,0x30,0x31,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x35,0x35,0x32,0x39,0x36, + 0x35,0x31,0x36,0x34,0x31,0x38,0x34,0x35,0x37,0x30,0x33,0x31,0x32,0x35,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x31,0x31,0x20,0x3d,0x20,0x32,0x2e,0x35,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x34,0x38, + 0x32,0x20,0x3d,0x20,0x63,0x61,0x6c,0x63,0x53,0x6f,0x66,0x74,0x73,0x68,0x61,0x64, + 0x6f,0x77,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x38,0x2c,0x20,0x70,0x61,0x72,0x61, + 0x6d,0x5f,0x39,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x30,0x2c,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x31,0x31,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x34,0x38,0x33,0x20,0x3d,0x20, + 0x64,0x69,0x66,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x20,0x5f,0x32,0x34,0x38,0x34,0x20,0x3d,0x20,0x5f,0x32,0x34,0x38,0x33, + 0x20,0x2a,0x20,0x5f,0x32,0x34,0x38,0x32,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x64,0x69,0x66,0x20,0x3d,0x20,0x5f,0x32,0x34,0x38,0x34,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6c,0x69,0x6e,0x20,0x3d,0x20,0x28,0x6c,0x69, + 0x6e,0x20,0x2b,0x20,0x28,0x28,0x28,0x63,0x6f,0x6c,0x20,0x2a,0x20,0x32,0x2e,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x37,0x36,0x38,0x33,0x37,0x31,0x35,0x38,0x32, + 0x30,0x33,0x31,0x32,0x35,0x29,0x20,0x2a,0x20,0x5f,0x32,0x34,0x38,0x34,0x29,0x20, + 0x2a,0x20,0x76,0x65,0x63,0x33,0x28,0x31,0x2e,0x32,0x39,0x39,0x39,0x39,0x39,0x39, + 0x35,0x32,0x33,0x31,0x36,0x32,0x38,0x34,0x31,0x37,0x39,0x36,0x38,0x37,0x35,0x2c, + 0x20,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x36,0x39,0x39,0x39,0x39,0x39,0x39,0x38, + 0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39,0x32,0x31,0x38,0x37,0x35, + 0x29,0x29,0x29,0x20,0x2b,0x20,0x28,0x28,0x76,0x65,0x63,0x33,0x28,0x31,0x2e,0x32, + 0x39,0x39,0x39,0x39,0x39,0x39,0x35,0x32,0x33,0x31,0x36,0x32,0x38,0x34,0x31,0x37, + 0x39,0x36,0x38,0x37,0x35,0x2c,0x20,0x31,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x36,0x39, + 0x39,0x39,0x39,0x39,0x39,0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34, + 0x39,0x32,0x31,0x38,0x37,0x35,0x29,0x20,0x2a,0x20,0x28,0x35,0x2e,0x30,0x20,0x2a, + 0x20,0x28,0x28,0x70,0x6f,0x77,0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74, + 0x28,0x5f,0x32,0x33,0x37,0x38,0x2c,0x20,0x5f,0x32,0x34,0x37,0x30,0x29,0x2c,0x20, + 0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x2c,0x20,0x31,0x36,0x2e,0x30,0x29, + 0x20,0x2a,0x20,0x5f,0x32,0x34,0x38,0x34,0x29,0x20,0x2a,0x20,0x28,0x30,0x2e,0x30, + 0x33,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x31,0x30,0x35,0x39,0x33,0x30,0x33,0x32, + 0x38,0x33,0x36,0x39,0x31,0x34,0x30,0x36,0x32,0x35,0x20,0x2b,0x20,0x28,0x30,0x2e, + 0x39,0x35,0x39,0x39,0x39,0x39,0x39,0x37,0x38,0x35,0x34,0x32,0x33,0x32,0x37,0x38, + 0x38,0x30,0x38,0x35,0x39,0x33,0x37,0x35,0x20,0x2a,0x20,0x70,0x6f,0x77,0x28,0x63, + 0x6c,0x61,0x6d,0x70,0x28,0x31,0x2e,0x30,0x20,0x2d,0x20,0x64,0x6f,0x74,0x28,0x5f, + 0x32,0x34,0x37,0x30,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x2d,0x30,0x2e,0x35,0x36, + 0x39,0x38,0x30,0x32,0x38,0x38,0x30,0x32,0x38,0x37,0x31,0x37,0x30,0x34,0x31,0x30, + 0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e,0x34,0x35,0x35,0x38,0x34,0x32,0x33, + 0x31,0x36,0x31,0x35,0x30,0x36,0x36,0x35,0x32,0x38,0x33,0x32,0x30,0x33,0x31,0x32, + 0x35,0x2c,0x20,0x2d,0x30,0x2e,0x36,0x38,0x33,0x37,0x36,0x33,0x34,0x34,0x34,0x34, + 0x32,0x33,0x36,0x37,0x35,0x35,0x33,0x37,0x31,0x30,0x39,0x33,0x37,0x35,0x29,0x29, + 0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x2c,0x20,0x35,0x2e,0x30, + 0x29,0x29,0x29,0x29,0x29,0x29,0x20,0x2a,0x20,0x6b,0x73,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x35,0x33, + 0x33,0x20,0x3d,0x20,0x73,0x71,0x72,0x74,0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x30, + 0x2e,0x35,0x20,0x2b,0x20,0x28,0x30,0x2e,0x35,0x20,0x2a,0x20,0x5f,0x32,0x33,0x37, + 0x38,0x2e,0x79,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29, + 0x20,0x2a,0x20,0x5f,0x32,0x34,0x35,0x39,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x73,0x70,0x65,0x20,0x3d,0x20,0x28,0x73, + 0x6d,0x6f,0x6f,0x74,0x68,0x73,0x74,0x65,0x70,0x28,0x2d,0x30,0x2e,0x32,0x30,0x30, + 0x30,0x30,0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37, + 0x36,0x39,0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x30,0x2e,0x32,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,0x39,0x38,0x30,0x32,0x33,0x32,0x32,0x33,0x38,0x37,0x36,0x39, + 0x35,0x33,0x31,0x32,0x35,0x2c,0x20,0x5f,0x32,0x33,0x39,0x30,0x2e,0x79,0x29,0x20, + 0x2a,0x20,0x5f,0x32,0x35,0x33,0x33,0x29,0x20,0x2a,0x20,0x28,0x30,0x2e,0x30,0x33, + 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x31,0x30,0x35,0x39,0x33,0x30,0x33,0x32,0x38, + 0x33,0x36,0x39,0x31,0x34,0x30,0x36,0x32,0x35,0x20,0x2b,0x20,0x28,0x30,0x2e,0x39, + 0x35,0x39,0x39,0x39,0x39,0x39,0x37,0x38,0x35,0x34,0x32,0x33,0x32,0x37,0x38,0x38, + 0x30,0x38,0x35,0x39,0x33,0x37,0x35,0x20,0x2a,0x20,0x70,0x6f,0x77,0x28,0x63,0x6c, + 0x61,0x6d,0x70,0x28,0x31,0x2e,0x30,0x20,0x2b,0x20,0x64,0x6f,0x74,0x28,0x5f,0x32, + 0x33,0x37,0x38,0x2c,0x20,0x72,0x64,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31, + 0x2e,0x30,0x29,0x2c,0x20,0x35,0x2e,0x30,0x29,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x31,0x32,0x20,0x3d,0x20,0x5f,0x32,0x33,0x37,0x33,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31, + 0x33,0x20,0x3d,0x20,0x5f,0x32,0x33,0x39,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31, + 0x34,0x20,0x3d,0x20,0x30,0x2e,0x30,0x31,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x35, + 0x35,0x32,0x39,0x36,0x35,0x31,0x36,0x34,0x31,0x38,0x34,0x35,0x37,0x30,0x33,0x31, + 0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61, + 0x74,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x35,0x20,0x3d,0x20,0x32,0x2e,0x35, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x5f,0x32,0x35,0x35,0x37,0x20,0x3d,0x20,0x63,0x61,0x6c,0x63,0x53,0x6f,0x66,0x74, + 0x73,0x68,0x61,0x64,0x6f,0x77,0x28,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x32,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x31,0x34,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x35,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32, + 0x35,0x35,0x38,0x20,0x3d,0x20,0x73,0x70,0x65,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x35,0x35,0x39,0x20,0x3d, + 0x20,0x5f,0x32,0x35,0x35,0x38,0x20,0x2a,0x20,0x5f,0x32,0x35,0x35,0x37,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x70,0x65,0x20,0x3d,0x20,0x5f,0x32, + 0x35,0x35,0x39,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x5f,0x32,0x35,0x36,0x37,0x20,0x3d,0x20,0x6c,0x69,0x6e,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32,0x36,0x31, + 0x38,0x20,0x3d,0x20,0x28,0x28,0x28,0x5f,0x32,0x35,0x36,0x37,0x20,0x2b,0x20,0x28, + 0x28,0x28,0x63,0x6f,0x6c,0x20,0x2a,0x20,0x30,0x2e,0x36,0x30,0x30,0x30,0x30,0x30, + 0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39,0x31,0x30,0x31,0x35,0x36,0x32, + 0x35,0x29,0x20,0x2a,0x20,0x5f,0x32,0x35,0x33,0x33,0x29,0x20,0x2a,0x20,0x76,0x65, + 0x63,0x33,0x28,0x30,0x2e,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36, + 0x30,0x34,0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20, + 0x30,0x2e,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35, + 0x37,0x39,0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x31,0x2e,0x31,0x34,0x39, + 0x39,0x39,0x39,0x39,0x37,0x36,0x31,0x35,0x38,0x31,0x34,0x32,0x30,0x38,0x39,0x38, + 0x34,0x33,0x37,0x35,0x29,0x29,0x29,0x20,0x2b,0x20,0x28,0x28,0x76,0x65,0x63,0x33, + 0x28,0x30,0x2e,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,0x39,0x36,0x30,0x34, + 0x36,0x34,0x34,0x37,0x37,0x35,0x33,0x39,0x30,0x36,0x32,0x35,0x2c,0x20,0x30,0x2e, + 0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39, + 0x31,0x30,0x31,0x35,0x36,0x32,0x35,0x2c,0x20,0x31,0x2e,0x32,0x39,0x39,0x39,0x39, + 0x39,0x39,0x35,0x32,0x33,0x31,0x36,0x32,0x38,0x34,0x31,0x37,0x39,0x36,0x38,0x37, + 0x35,0x29,0x20,0x2a,0x20,0x28,0x32,0x2e,0x30,0x20,0x2a,0x20,0x5f,0x32,0x35,0x35, + 0x39,0x29,0x29,0x20,0x2a,0x20,0x6b,0x73,0x29,0x29,0x20,0x2b,0x20,0x28,0x28,0x28, + 0x63,0x6f,0x6c,0x20,0x2a,0x20,0x30,0x2e,0x35,0x35,0x30,0x30,0x30,0x30,0x30,0x31, + 0x31,0x39,0x32,0x30,0x39,0x32,0x38,0x39,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35, + 0x29,0x20,0x2a,0x20,0x28,0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x64,0x6f,0x74,0x28, + 0x5f,0x32,0x33,0x37,0x38,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x36,0x34, + 0x30,0x31,0x38,0x34,0x34,0x30,0x32,0x34,0x36,0x35,0x38,0x32,0x30,0x33,0x31,0x32, + 0x35,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x30,0x2e,0x37,0x36,0x38,0x32,0x32,0x31, + 0x32,0x35,0x39,0x31,0x31,0x37,0x31,0x32,0x36,0x34,0x36,0x34,0x38,0x34,0x33,0x37, + 0x35,0x29,0x29,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x20,0x2a, + 0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x31,0x2e,0x30,0x20,0x2d,0x20,0x5f,0x32,0x33, + 0x37,0x33,0x2e,0x79,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29, + 0x20,0x2a,0x20,0x5f,0x32,0x34,0x35,0x39,0x29,0x29,0x20,0x2a,0x20,0x76,0x65,0x63, + 0x33,0x28,0x30,0x2e,0x32,0x35,0x29,0x29,0x29,0x20,0x2b,0x20,0x28,0x28,0x63,0x6f, + 0x6c,0x20,0x2a,0x20,0x30,0x2e,0x32,0x35,0x29,0x20,0x2a,0x20,0x28,0x70,0x6f,0x77, + 0x28,0x63,0x6c,0x61,0x6d,0x70,0x28,0x31,0x2e,0x30,0x20,0x2b,0x20,0x64,0x6f,0x74, + 0x28,0x5f,0x32,0x33,0x37,0x38,0x2c,0x20,0x72,0x64,0x29,0x2c,0x20,0x30,0x2e,0x30, + 0x2c,0x20,0x31,0x2e,0x30,0x29,0x2c,0x20,0x32,0x2e,0x30,0x29,0x20,0x2a,0x20,0x5f, + 0x32,0x34,0x35,0x39,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x6c,0x69,0x6e,0x20,0x3d,0x20,0x5f,0x32,0x36,0x31,0x38,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x20,0x3d,0x20,0x6d,0x69,0x78,0x28,0x5f, + 0x32,0x36,0x31,0x38,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x36,0x39,0x39, + 0x39,0x39,0x39,0x39,0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39, + 0x32,0x31,0x38,0x37,0x35,0x2c,0x20,0x30,0x2e,0x36,0x39,0x39,0x39,0x39,0x39,0x39, + 0x38,0x38,0x30,0x37,0x39,0x30,0x37,0x31,0x30,0x34,0x34,0x39,0x32,0x31,0x38,0x37, + 0x35,0x2c,0x20,0x30,0x2e,0x38,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x36,0x31,0x35, + 0x38,0x31,0x34,0x32,0x30,0x38,0x39,0x38,0x34,0x33,0x37,0x35,0x29,0x2c,0x20,0x76, + 0x65,0x63,0x33,0x28,0x31,0x2e,0x30,0x20,0x2d,0x20,0x65,0x78,0x70,0x28,0x28,0x28, + 0x28,0x2d,0x39,0x2e,0x39,0x39,0x39,0x39,0x39,0x39,0x37,0x34,0x37,0x33,0x37,0x38, + 0x37,0x35,0x31,0x36,0x33,0x35,0x35,0x35,0x31,0x34,0x35,0x32,0x36,0x33,0x36,0x37, + 0x31,0x38,0x38,0x65,0x2d,0x30,0x35,0x29,0x20,0x2a,0x20,0x5f,0x32,0x33,0x36,0x30, + 0x29,0x20,0x2a,0x20,0x5f,0x32,0x33,0x36,0x30,0x29,0x20,0x2a,0x20,0x5f,0x32,0x33, + 0x36,0x30,0x29,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20, + 0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x63,0x6c,0x61,0x6d,0x70,0x28,0x63,0x6f, + 0x6c,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x29,0x2c,0x20,0x76,0x65, + 0x63,0x33,0x28,0x31,0x2e,0x30,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x76,0x65,0x63, + 0x34,0x20,0x6d,0x61,0x69,0x6e,0x49,0x6d,0x61,0x67,0x65,0x28,0x76,0x65,0x63,0x32, + 0x20,0x66,0x72,0x61,0x67,0x43,0x6f,0x6f,0x72,0x64,0x29,0x0a,0x7b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x36,0x38,0x36,0x20,0x3d,0x20,0x66, + 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x7a,0x77,0x20,0x2f, + 0x20,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x79, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x32,0x37,0x30, + 0x35,0x20,0x3d,0x20,0x28,0x30,0x2e,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31, + 0x34,0x39,0x30,0x31,0x31,0x36,0x31,0x31,0x39,0x33,0x38,0x34,0x37,0x36,0x35,0x36, + 0x32,0x35,0x20,0x2a,0x20,0x28,0x33,0x32,0x2e,0x30,0x20,0x2b,0x20,0x28,0x66,0x73, + 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x2e,0x78,0x20,0x2a,0x20,0x31, + 0x2e,0x35,0x29,0x29,0x29,0x20,0x2b,0x20,0x28,0x37,0x2e,0x30,0x20,0x2a,0x20,0x5f, + 0x32,0x36,0x38,0x36,0x2e,0x78,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63, + 0x33,0x20,0x5f,0x32,0x37,0x32,0x31,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30, + 0x2e,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x36,0x30,0x30, + 0x30,0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39,0x31,0x30,0x31, + 0x35,0x36,0x32,0x35,0x29,0x20,0x2b,0x20,0x76,0x65,0x63,0x33,0x28,0x34,0x2e,0x35, + 0x20,0x2a,0x20,0x63,0x6f,0x73,0x28,0x5f,0x32,0x37,0x30,0x35,0x29,0x2c,0x20,0x31, + 0x2e,0x32,0x39,0x39,0x39,0x39,0x39,0x39,0x35,0x32,0x33,0x31,0x36,0x32,0x38,0x34, + 0x31,0x37,0x39,0x36,0x38,0x37,0x35,0x20,0x2b,0x20,0x28,0x32,0x2e,0x30,0x20,0x2a, + 0x20,0x5f,0x32,0x36,0x38,0x36,0x2e,0x79,0x29,0x2c,0x20,0x34,0x2e,0x35,0x20,0x2a, + 0x20,0x73,0x69,0x6e,0x28,0x5f,0x32,0x37,0x30,0x35,0x29,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x5f, + 0x32,0x37,0x32,0x31,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x31,0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e, + 0x35,0x2c,0x20,0x2d,0x30,0x2e,0x35,0x2c,0x20,0x2d,0x30,0x2e,0x36,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,0x33,0x38,0x34,0x31,0x38,0x35,0x37,0x39,0x31,0x30,0x31,0x35, + 0x36,0x32,0x35,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x5f,0x32,0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x6d,0x61,0x74,0x33,0x20,0x5f,0x32,0x37,0x32,0x39,0x20,0x3d,0x20, + 0x73,0x65,0x74,0x43,0x61,0x6d,0x65,0x72,0x61,0x28,0x70,0x61,0x72,0x61,0x6d,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x31,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x32,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x74,0x6f,0x74, + 0x20,0x3d,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x37,0x33,0x39,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x32,0x28,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d, + 0x2e,0x79,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61, + 0x72,0x61,0x6d,0x5f,0x33,0x20,0x3d,0x20,0x5f,0x32,0x37,0x32,0x31,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x20, + 0x3d,0x20,0x5f,0x32,0x37,0x32,0x39,0x20,0x2a,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c, + 0x69,0x7a,0x65,0x28,0x76,0x65,0x63,0x33,0x28,0x28,0x28,0x66,0x72,0x61,0x67,0x43, + 0x6f,0x6f,0x72,0x64,0x20,0x2a,0x20,0x32,0x2e,0x30,0x29,0x20,0x2d,0x20,0x66,0x73, + 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x79,0x29,0x20,0x2f, + 0x20,0x5f,0x32,0x37,0x33,0x39,0x2c,0x20,0x32,0x2e,0x35,0x29,0x29,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x20, + 0x3d,0x20,0x5f,0x32,0x37,0x32,0x39,0x20,0x2a,0x20,0x6e,0x6f,0x72,0x6d,0x61,0x6c, + 0x69,0x7a,0x65,0x28,0x76,0x65,0x63,0x33,0x28,0x28,0x28,0x28,0x66,0x72,0x61,0x67, + 0x43,0x6f,0x6f,0x72,0x64,0x20,0x2b,0x20,0x76,0x65,0x63,0x32,0x28,0x31,0x2e,0x30, + 0x2c,0x20,0x30,0x2e,0x30,0x29,0x29,0x20,0x2a,0x20,0x32,0x2e,0x30,0x29,0x20,0x2d, + 0x20,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x79, + 0x29,0x20,0x2f,0x20,0x5f,0x32,0x37,0x33,0x39,0x2c,0x20,0x32,0x2e,0x35,0x29,0x29, + 0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x61,0x72,0x61,0x6d, + 0x5f,0x36,0x20,0x3d,0x20,0x5f,0x32,0x37,0x32,0x39,0x20,0x2a,0x20,0x6e,0x6f,0x72, + 0x6d,0x61,0x6c,0x69,0x7a,0x65,0x28,0x76,0x65,0x63,0x33,0x28,0x28,0x28,0x28,0x66, + 0x72,0x61,0x67,0x43,0x6f,0x6f,0x72,0x64,0x20,0x2b,0x20,0x76,0x65,0x63,0x32,0x28, + 0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x29,0x20,0x2a,0x20,0x32,0x2e,0x30, + 0x29,0x20,0x2d,0x20,0x66,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d, + 0x2e,0x78,0x79,0x29,0x20,0x2f,0x20,0x5f,0x32,0x37,0x33,0x39,0x2c,0x20,0x32,0x2e, + 0x35,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x33,0x20,0x5f,0x32, + 0x38,0x30,0x34,0x20,0x3d,0x20,0x74,0x6f,0x74,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76, + 0x65,0x63,0x33,0x20,0x5f,0x32,0x38,0x30,0x35,0x20,0x3d,0x20,0x5f,0x32,0x38,0x30, + 0x34,0x20,0x2b,0x20,0x70,0x6f,0x77,0x28,0x72,0x65,0x6e,0x64,0x65,0x72,0x28,0x70, + 0x61,0x72,0x61,0x6d,0x5f,0x33,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x34,0x2c, + 0x20,0x70,0x61,0x72,0x61,0x6d,0x5f,0x35,0x2c,0x20,0x70,0x61,0x72,0x61,0x6d,0x5f, + 0x36,0x29,0x2c,0x20,0x76,0x65,0x63,0x33,0x28,0x30,0x2e,0x34,0x35,0x34,0x34,0x39, + 0x39,0x39,0x38,0x39,0x37,0x34,0x38,0x30,0x30,0x31,0x30,0x39,0x38,0x36,0x33,0x32, + 0x38,0x31,0x32,0x35,0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x74,0x6f,0x74,0x20, + 0x3d,0x20,0x5f,0x32,0x38,0x30,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74, + 0x75,0x72,0x6e,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,0x38,0x30,0x35,0x2c,0x20, + 0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61, + 0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20, + 0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x75,0x76,0x20,0x2a,0x20,0x66,0x73,0x5f, + 0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x79,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x28, + 0x28,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x2c,0x20,0x75,0x76, + 0x29,0x20,0x2a,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x29,0x20,0x2a,0x20,0x39,0x2e,0x39, + 0x39,0x39,0x39,0x39,0x39,0x37,0x34,0x37,0x33,0x37,0x38,0x37,0x35,0x31,0x36,0x33, + 0x35,0x35,0x35,0x31,0x34,0x35,0x32,0x36,0x33,0x36,0x37,0x31,0x38,0x38,0x65,0x2d, + 0x30,0x36,0x29,0x20,0x2b,0x20,0x6d,0x61,0x69,0x6e,0x49,0x6d,0x61,0x67,0x65,0x28, + 0x70,0x61,0x72,0x61,0x6d,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +}; +#if !defined(SOKOL_GFX_INCLUDED) + #error "Please include sokol_gfx.h before rt_glsl.h" +#endif +static inline const sg_shader_desc* rt_shader_desc(void) { + if (sg_query_backend() == SG_BACKEND_GLCORE33) { + static sg_shader_desc desc; + static bool valid; + if (!valid) { + valid = true; + desc.attrs[0].name = "pos"; + desc.attrs[1].name = "color0"; + desc.attrs[2].name = "texcoord0"; + desc.vs.source = vs_source_glsl330; + desc.vs.entry = "main"; + desc.vs.uniform_blocks[0].size = 64; + desc.vs.uniform_blocks[0].uniforms[0].name = "vs_params"; + desc.vs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4; + desc.vs.uniform_blocks[0].uniforms[0].array_count = 4; + desc.fs.source = fs_source_glsl330; + desc.fs.entry = "main"; + desc.fs.uniform_blocks[0].size = 32; + desc.fs.uniform_blocks[0].uniforms[0].name = "fs_params"; + desc.fs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4; + desc.fs.uniform_blocks[0].uniforms[0].array_count = 2; + desc.fs.images[0].name = "tex"; + desc.fs.images[0].type = SG_IMAGETYPE_2D; + desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; + desc.label = "rt_shader"; + }; + return &desc; + } + return 0; +} diff --git a/examples/sokol/rt_glsl/rt_glsl.v b/examples/sokol/rt_glsl/rt_glsl.v new file mode 100644 index 0000000000..f7ae6064f1 --- /dev/null +++ b/examples/sokol/rt_glsl/rt_glsl.v @@ -0,0 +1,422 @@ +/********************************************************************** +* +* Sokol 3d cube demo +* +* Copyright (c) 2021 Dario Deledda. All rights reserved. +* Use of this source code is governed by an MIT license +* that can be found in the LICENSE file. +* +* HOW TO COMPILE SHADERS: +* - donwload sokol shader tool from: https://github.com/floooh/sokol-tools/blob/master/docs/sokol-shdc.md +* - compile shader with: +* linux : sokol-shdc --input rt_glsl.glsl --output rt_glsl.h --slang glsl330 +* windows: sokol-shdc.exe --input rt_glsl.glsl --output rt_glsl.h --slang glsl330 +* +* --slang parameter can be: +* - glsl330: desktop GL +* - glsl100: GLES2 / WebGL +* - glsl300es: GLES3 / WebGL2 +* - hlsl4: D3D11 +* - hlsl5: D3D11 +* - metal_macos: Metal on macOS +* - metal_ios: Metal on iOS device +* - metal_sim: Metal on iOS simulator +* - wgpu: WebGPU +* +* you can have multiple platforms at the same time passing parameters like this: --slang glsl330:hlsl5:metal_macos +* for further infos have a look at the sokol shader tool docs. +* +* TODO: +* - frame counter +**********************************************************************/ +import gg +import gx +//import math + +import sokol.sapp +import sokol.gfx +import sokol.sgl + +import time + +const ( + win_width = 800 + win_height = 800 + bg_color = gx.white +) + +struct App { +mut: + gg &gg.Context + texture C.sg_image + init_flag bool + frame_count int + + mouse_x int = -1 + mouse_y int = -1 + + // glsl + cube_pip_glsl C.sg_pipeline + cube_bind C.sg_bindings + + // time + ticks i64 +} + +/****************************************************************************** +* +* GLSL Include and functions +* +******************************************************************************/ +#flag -I @VROOT/. +#include "HandmadeMath.h" +#include "rt_glsl.h" +#include "default_include.h" +fn C.rt_shader_desc() &C.sg_shader_desc + +fn C.calc_matrices(res voidptr,w f32, h f32, rx f32, ry f32, scale f32) + +/****************************************************************************** +* +* Texture functions +* +******************************************************************************/ +fn create_texture(w int, h int, buf byteptr) C.sg_image{ + sz := w * h * 4 + mut img_desc := C.sg_image_desc{ + width: w + height: h + num_mipmaps: 0 + min_filter: .linear + mag_filter: .linear + //usage: .dynamic + wrap_u: .clamp_to_edge + wrap_v: .clamp_to_edge + label: &byte(0) + d3d11_texture: 0 + } + // comment if .dynamic is enabled + img_desc.content.subimage[0][0] = C.sg_subimage_content{ + ptr: buf + size: sz + } + + sg_img := C.sg_make_image(&img_desc) + return sg_img +} + +fn destroy_texture(sg_img C.sg_image){ + C.sg_destroy_image(sg_img) +} + +// Use only if usage: .dynamic is enabled +fn update_text_texture(sg_img C.sg_image, w int, h int, buf byteptr){ + sz := w * h * 4 + mut tmp_sbc := C.sg_image_content{} + tmp_sbc.subimage[0][0] = C.sg_subimage_content { + ptr: buf + size: sz + } + C.sg_update_image(sg_img, &tmp_sbc) +} + +/****************************************************************************** +* +* Draw functions +* +******************************************************************************/ +/* + Cube vertex buffer with packed vertex formats for color and texture coords. + Note that a vertex format which must be portable across all + backends must only use the normalized integer formats + (BYTE4N, UBYTE4N, SHORT2N, SHORT4N), which can be converted + to floating point formats in the vertex shader inputs. + The reason is that D3D11 cannot convert from non-normalized + formats to floating point inputs (only to integer inputs), + and WebGL2 / GLES2 don't support integer vertex shader inputs. +*/ + +struct Vertex_t { + x f32 + y f32 + z f32 + color u32 + + //u u16 // for compatibility with D3D11 + //v u16 // for compatibility with D3D11 + u f32 + v f32 +} + +fn init_cube_glsl(mut app App) { + /* cube vertex buffer */ + //d := u16(32767) // for compatibility with D3D11, 32767 stand for 1 + d := f32(1.0) + c := u32(0xFFFFFF_FF) // color RGBA8 + vertices := [ + + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, d}, + Vertex_t{-1.0, 1.0, -1.0, c, 0, d}, + + Vertex_t{-1.0, -1.0, 1.0, c, 0, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, 1.0, 1.0, c, 0, d}, + + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, d}, + Vertex_t{-1.0, -1.0, 1.0, c, 0, d}, + + Vertex_t{ 1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{ 1.0, 1.0, -1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, 1.0, c, 0, d}, + + Vertex_t{-1.0, -1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, -1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, -1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, -1.0, -1.0, c, 0, d}, + + Vertex_t{-1.0, 1.0, -1.0, c, 0, 0}, + Vertex_t{-1.0, 1.0, 1.0, c, d, 0}, + Vertex_t{ 1.0, 1.0, 1.0, c, d, d}, + Vertex_t{ 1.0, 1.0, -1.0, c, 0, d}, + + ] + + mut vert_buffer_desc := C.sg_buffer_desc{} + unsafe {C.memset(&vert_buffer_desc, 0, sizeof(vert_buffer_desc))} + vert_buffer_desc.size = vertices.len * int(sizeof(Vertex_t)) + vert_buffer_desc.content = byteptr(vertices.data) + vert_buffer_desc.@type = .vertexbuffer + vert_buffer_desc.label = "cube-vertices".str + vbuf := gfx.make_buffer(&vert_buffer_desc) + + /* create an index buffer for the cube */ + indices := [ + u16(0), 1, 2, 0, 2, 3, + 6, 5, 4, 7, 6, 4, + 8, 9, 10, 8, 10, 11, + 14, 13, 12, 15, 14, 12, + 16, 17, 18, 16, 18, 19, + 22, 21, 20, 23, 22, 20 + ] + + mut index_buffer_desc := C.sg_buffer_desc{} + unsafe {C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc))} + index_buffer_desc.size = indices.len * int(sizeof(u16)) + index_buffer_desc.content = byteptr(indices.data) + index_buffer_desc.@type = .indexbuffer + index_buffer_desc.label = "cube-indices".str + ibuf := gfx.make_buffer(&index_buffer_desc) + + /* create shader */ + shader := gfx.make_shader(C.rt_shader_desc()) + + mut pipdesc := C.sg_pipeline_desc{} + unsafe {C.memset(&pipdesc, 0, sizeof(pipdesc))} + pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_t)) + + // the constants [C.ATTR_vs_pos, C.ATTR_vs_color0, C.ATTR_vs_texcoord0] are generated by sokol-shdc + pipdesc.layout.attrs[C.ATTR_vs_pos ].format = .float3 // x,y,z as f32 + pipdesc.layout.attrs[C.ATTR_vs_color0 ].format = .ubyte4n // color as u32 + pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .float2 // u,v as f32 + //pipdesc.layout.attrs[C.ATTR_vs_texcoord0].format = .short2n // u,v as u16 + + pipdesc.shader = shader + pipdesc.index_type = .uint16 + + pipdesc.depth_stencil = C.sg_depth_stencil_state{ + depth_write_enabled: true + depth_compare_func : gfx.CompareFunc(C.SG_COMPAREFUNC_LESS_EQUAL) + } + pipdesc.rasterizer = C.sg_rasterizer_state { + cull_mode: .back + } + pipdesc.label = "glsl_shader pipeline".str + + app.cube_bind.vertex_buffers[0] = vbuf + app.cube_bind.index_buffer = ibuf + app.cube_bind.fs_images[C.SLOT_tex] = app.texture + app.cube_pip_glsl = gfx.make_pipeline(&pipdesc) + println("GLSL init DONE!") +} + +fn draw_cube_glsl(app App){ + if app.init_flag == false { + return + } + + ws := gg.window_size() + ratio := f32(ws.width) / ws.height + dw := f32(ws.width / 2) + dh := f32(ws.height / 2) + + mut res := [f32(0),0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]! + + // use the following commented lines to rotate the 3d glsl cube + // rot := [f32(app.mouse_y), f32(app.mouse_x)] + // C.calc_matrices( voidptr(&res), dw, dh, rot[0], rot[1] ,2.3) + C.calc_matrices( voidptr(&res), dw, dh, 0, 0 ,2.3) + gfx.apply_viewport(0, 0, ws.width, ws.height, true) + + // apply the pipline and bindings + gfx.apply_pipeline(app.cube_pip_glsl) + gfx.apply_bindings(app.cube_bind) + + //*************** + // Uniforms + //*************** + // passing the view matrix as uniform + // res is a 4x4 matrix of f32 thus: 4*16 byte of size + gfx.apply_uniforms(C.SG_SHADERSTAGE_VS, C.SLOT_vs_params, &res, int(sizeof(res)) ) + + // fragment shader uniforms + time_ticks := f32(time.ticks() - app.ticks) / 1000 + mut tmp_fs_params := [ + f32(ws.width), ws.height * ratio, // x,y resolution to pass to FS + app.mouse_x, // mouse x + ws.height - app.mouse_y*2, // mouse y scaled + time_ticks, // time as f32 + app.frame_count, // frame count + 0,0 // padding bytes , see "fs_params" struct paddings in rt_glsl.h + ]! + gfx.apply_uniforms(C.SG_SHADERSTAGE_FS, C.SLOT_fs_params, &tmp_fs_params, int(sizeof(tmp_fs_params))) + + // 3 vertices for triangle * 2 triangles per face * 6 faces = 36 vertices to draw + gfx.draw(0, (3 * 2) * 6, 1) + gfx.end_pass() + gfx.commit() +} + +fn frame(mut app App) { + ws := gg.window_size() + + // clear + mut color_action := C.sg_color_attachment_action{ + action: gfx.Action(C.SG_ACTION_CLEAR) + } + color_action.val[0] = 0 + color_action.val[1] = 0 + color_action.val[2] = 0 + color_action.val[3] = 1.0 + mut pass_action := C.sg_pass_action{} + pass_action.colors[0] = color_action + gfx.begin_default_pass(&pass_action, ws.width, ws.height) + + // glsl cube + draw_cube_glsl(app) + app.frame_count++ +} + +/****************************************************************************** +* +* Init / Cleanup +* +******************************************************************************/ +fn my_init(mut app App) { + // set max vertices, + // for a large number of the same type of object it is better use the instances!! + desc := sapp.create_desc() + gfx.setup(&desc) + sgl_desc := C.sgl_desc_t{ + max_vertices: 50 * 65536 + } + sgl.setup(&sgl_desc) + + // create chessboard texture 256*256 RGBA + w := 256 + h := 256 + sz := w * h * 4 + tmp_txt := malloc(sz) + mut i := 0 + for i < sz { + unsafe { + y := (i >> 0x8) >> 5 // 8 cell + x := (i & 0xFF) >> 5 // 8 cell + // upper left corner + if x==0 && y==0 { + tmp_txt[i ] = byte(0xFF) + tmp_txt[i+1] = byte(0) + tmp_txt[i+2] = byte(0) + tmp_txt[i+3] = byte(0xFF) + } + // low right corner + else if x==7 && y==7 { + tmp_txt[i ] = byte(0) + tmp_txt[i+1] = byte(0xFF) + tmp_txt[i+2] = byte(0) + tmp_txt[i+3] = byte(0xFF) + } else { + col := if ((x+y) & 1) == 1 {0xFF} else {128} + tmp_txt[i ] = byte(col) // red + tmp_txt[i+1] = byte(col) // green + tmp_txt[i+2] = byte(col) // blue + tmp_txt[i+3] = byte(0xFF) // alpha + } + i += 4 + } + } + app.texture = create_texture(w, h, tmp_txt) + free(tmp_txt) + + // glsl + init_cube_glsl(mut app) + app.init_flag = true +} + +fn cleanup(mut app App) { + gfx.shutdown() +} + +/****************************************************************************** +* +* event +* +******************************************************************************/ +fn my_event_manager(mut ev sapp.Event, mut app App) { + if ev.typ == .mouse_move { + app.mouse_x = int(ev.mouse_x) + app.mouse_y = int(ev.mouse_y) + } + if ev.typ == .touches_began || ev.typ == .touches_moved { + if ev.num_touches > 0 { + touch_point := ev.touches[0] + app.mouse_x = int(touch_point.pos_x) + app.mouse_y = int(touch_point.pos_y) + } + } +} + +/****************************************************************************** +* +* Main +* +******************************************************************************/ +[console] +fn main(){ + // App init + mut app := &App{ + gg: 0 + } + + app.gg = gg.new_context({ + width: win_width + height: win_height + use_ortho: true // This is needed for 2D drawing + create_window: true + window_title: '3D Ray Marching Cube' + user_data: app + bg_color: bg_color + frame_fn: frame + init_fn: my_init + cleanup_fn: cleanup + event_fn: my_event_manager + }) + + app.ticks = time.ticks() + app.gg.run() +} diff --git a/examples/sokol/rt_glsl/v.mod b/examples/sokol/rt_glsl/v.mod new file mode 100644 index 0000000000..e69de29bb2